mirror of https://github.com/aria2/aria2
Use ServerStat to find faster server.
parent
ba6ab14235
commit
2906484345
|
@ -92,7 +92,8 @@ AbstractCommand::AbstractCommand
|
|||
socketRecvBuffer_(socketRecvBuffer),
|
||||
checkSocketIsReadable_(false), checkSocketIsWritable_(false),
|
||||
nameResolverCheck_(false),
|
||||
incNumConnection_(incNumConnection)
|
||||
incNumConnection_(incNumConnection),
|
||||
serverStatTimer_(global::wallclock)
|
||||
{
|
||||
if(socket_ && socket_->isOpen()) {
|
||||
setReadCheckSocket(socket_);
|
||||
|
@ -117,6 +118,22 @@ AbstractCommand::~AbstractCommand() {
|
|||
}
|
||||
}
|
||||
|
||||
void AbstractCommand::useFasterRequest
|
||||
(const SharedHandle<Request>& fasterRequest)
|
||||
{
|
||||
A2_LOG_INFO(fmt("CUID#%lld - Use faster Request hostname=%s, port=%u",
|
||||
getCuid(),
|
||||
fasterRequest->getHost().c_str(),
|
||||
fasterRequest->getPort()));
|
||||
// Cancel current Request object and use faster one.
|
||||
fileEntry_->removeRequest(req_);
|
||||
Command* command =
|
||||
InitiateConnectionCommandFactory::createInitiateConnectionCommand
|
||||
(getCuid(), fasterRequest, fileEntry_, requestGroup_, e_);
|
||||
e_->setNoWait(true);
|
||||
e_->addCommand(command);
|
||||
}
|
||||
|
||||
bool AbstractCommand::execute() {
|
||||
A2_LOG_DEBUG(fmt("CUID#%lld - socket: read:%d, write:%d, hup:%d, err:%d",
|
||||
getCuid(),
|
||||
|
@ -158,17 +175,25 @@ bool AbstractCommand::execute() {
|
|||
!getPieceStorage()->hasMissingUnusedPiece()) {
|
||||
SharedHandle<Request> fasterRequest = fileEntry_->findFasterRequest(req_);
|
||||
if(fasterRequest) {
|
||||
A2_LOG_INFO(fmt("CUID#%lld - Use faster Request hostname=%s, port=%u",
|
||||
getCuid(),
|
||||
fasterRequest->getHost().c_str(),
|
||||
fasterRequest->getPort()));
|
||||
// Cancel current Request object and use faster one.
|
||||
fileEntry_->removeRequest(req_);
|
||||
Command* command =
|
||||
InitiateConnectionCommandFactory::createInitiateConnectionCommand
|
||||
(getCuid(), fasterRequest, fileEntry_, requestGroup_, e_);
|
||||
e_->setNoWait(true);
|
||||
e_->addCommand(command);
|
||||
useFasterRequest(fasterRequest);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Don't use this feature if PREF_MAX_{OVERALL_}DOWNLOAD_LIMIT
|
||||
// is used
|
||||
if(e_->getRequestGroupMan()->getMaxOverallDownloadSpeedLimit() == 0 &&
|
||||
requestGroup_->getMaxDownloadSpeedLimit() == 0 &&
|
||||
serverStatTimer_.difference(global::wallclock) >= 10) {
|
||||
serverStatTimer_ = global::wallclock;
|
||||
std::vector<std::pair<size_t, std::string> > usedHosts;
|
||||
if(getOption()->getAsBool(PREF_SELECT_LEAST_USED_HOST)) {
|
||||
getDownloadEngine()->getRequestGroupMan()->getUsedHosts(usedHosts);
|
||||
}
|
||||
SharedHandle<Request> fasterRequest =
|
||||
fileEntry_->findFasterRequest
|
||||
(req_, usedHosts, e_->getRequestGroupMan()->getServerStatMan());
|
||||
if(fasterRequest) {
|
||||
useFasterRequest(fasterRequest);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,9 +85,10 @@ private:
|
|||
bool nameResolverCheck_;
|
||||
|
||||
bool incNumConnection_;
|
||||
Timer serverStatTimer_;
|
||||
|
||||
size_t calculateMinSplitSize() const;
|
||||
|
||||
void useFasterRequest(const SharedHandle<Request>& fasterRequest);
|
||||
#ifdef ENABLE_ASYNC_DNS
|
||||
void setNameResolverCheck(const SharedHandle<AsyncNameResolver>& resolver);
|
||||
|
||||
|
|
|
@ -56,18 +56,6 @@ FeedbackURISelector::FeedbackURISelector
|
|||
|
||||
FeedbackURISelector::~FeedbackURISelector() {}
|
||||
|
||||
namespace {
|
||||
class ServerStatFaster {
|
||||
public:
|
||||
bool operator()(const std::pair<SharedHandle<ServerStat>, std::string> lhs,
|
||||
const std::pair<SharedHandle<ServerStat>, std::string> rhs)
|
||||
const
|
||||
{
|
||||
return lhs.first->getDownloadSpeed() > rhs.first->getDownloadSpeed();
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
std::string FeedbackURISelector::select
|
||||
(FileEntry* fileEntry,
|
||||
const std::vector<std::pair<size_t, std::string> >& usedHosts)
|
||||
|
|
|
@ -46,6 +46,8 @@
|
|||
#include "uri.h"
|
||||
#include "PeerStat.h"
|
||||
#include "fmt.h"
|
||||
#include "ServerStatMan.h"
|
||||
#include "ServerStat.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
||||
|
@ -221,6 +223,57 @@ FileEntry::findFasterRequest(const SharedHandle<Request>& base)
|
|||
return SharedHandle<Request>();
|
||||
}
|
||||
|
||||
SharedHandle<Request>
|
||||
FileEntry::findFasterRequest
|
||||
(const SharedHandle<Request>& base,
|
||||
const std::vector<std::pair<size_t, std::string> >& usedHosts,
|
||||
const SharedHandle<ServerStatMan>& serverStatMan)
|
||||
{
|
||||
const int startupIdleTime = 10;
|
||||
const unsigned int SPEED_THRESHOLD = 20*1024;
|
||||
if(lastFasterReplace_.difference(global::wallclock) < startupIdleTime) {
|
||||
return SharedHandle<Request>();
|
||||
}
|
||||
const SharedHandle<PeerStat>& basestat = base->getPeerStat();
|
||||
A2_LOG_DEBUG("Search faster server using ServerStat.");
|
||||
// Use first 10 good URIs to introduce some randomness.
|
||||
const size_t NUM_URI = 10;
|
||||
std::vector<std::pair<SharedHandle<ServerStat>, std::string> > fastCands;
|
||||
std::vector<std::string> normCands;
|
||||
for(std::deque<std::string>::const_iterator i = uris_.begin(),
|
||||
eoi = uris_.end(); i != eoi && fastCands.size() < NUM_URI; ++i) {
|
||||
uri::UriStruct us;
|
||||
if(!uri::parse(us, *i)) {
|
||||
continue;
|
||||
}
|
||||
if(findSecond(usedHosts.begin(), usedHosts.end(), us.host) !=
|
||||
usedHosts.end()) {
|
||||
A2_LOG_DEBUG(fmt("%s is in usedHosts, not considered", (*i).c_str()));
|
||||
continue;
|
||||
}
|
||||
SharedHandle<ServerStat> ss = serverStatMan->find(us.host, us.protocol);
|
||||
if(ss && ss->isOK()) {
|
||||
if((basestat &&
|
||||
ss->getDownloadSpeed() > basestat->calculateDownloadSpeed()*1.5) ||
|
||||
(!basestat && ss->getDownloadSpeed() > SPEED_THRESHOLD)) {
|
||||
fastCands.push_back(std::make_pair(ss, *i));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!fastCands.empty()) {
|
||||
A2_LOG_DEBUG("Selected from fastCands");
|
||||
std::sort(fastCands.begin(), fastCands.end(), ServerStatFaster());
|
||||
SharedHandle<Request> fastestRequest(new Request());
|
||||
fastestRequest->setUri(fastCands.front().second);
|
||||
fastestRequest->setReferer(base->getReferer());
|
||||
inFlightRequests_.push_back(fastestRequest);
|
||||
lastFasterReplace_ = global::wallclock;
|
||||
return fastestRequest;
|
||||
}
|
||||
A2_LOG_DEBUG("No faster server found.");
|
||||
return SharedHandle<Request>();
|
||||
}
|
||||
|
||||
namespace {
|
||||
class RequestFaster {
|
||||
public:
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
namespace aria2 {
|
||||
|
||||
class URISelector;
|
||||
class ServerStatMan;
|
||||
|
||||
class FileEntry {
|
||||
private:
|
||||
|
@ -169,6 +170,13 @@ public:
|
|||
// removed from the pool and returned.
|
||||
SharedHandle<Request> findFasterRequest(const SharedHandle<Request>& base);
|
||||
|
||||
// Finds faster server using ServerStatMan.
|
||||
SharedHandle<Request>
|
||||
findFasterRequest
|
||||
(const SharedHandle<Request>& base,
|
||||
const std::vector<std::pair<size_t, std::string> >& usedHosts,
|
||||
const SharedHandle<ServerStatMan>& serverStatMan);
|
||||
|
||||
void poolRequest(const SharedHandle<Request>& request);
|
||||
|
||||
bool removeRequest(const SharedHandle<Request>& request);
|
||||
|
|
|
@ -294,6 +294,11 @@ public:
|
|||
|
||||
// Returns currently used hosts and its use count.
|
||||
void getUsedHosts(std::vector<std::pair<size_t, std::string> >& usedHosts);
|
||||
|
||||
const SharedHandle<ServerStatMan>& getServerStatMan() const
|
||||
{
|
||||
return serverStatMan_;
|
||||
}
|
||||
};
|
||||
|
||||
typedef SharedHandle<RequestGroupMan> RequestGroupManHandle;
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <string>
|
||||
#include <iosfwd>
|
||||
|
||||
#include "SharedHandle.h"
|
||||
#include "TimeA2.h"
|
||||
|
||||
namespace aria2 {
|
||||
|
@ -167,6 +168,16 @@ private:
|
|||
|
||||
std::ostream& operator<<(std::ostream& o, const ServerStat& serverStat);
|
||||
|
||||
class ServerStatFaster {
|
||||
public:
|
||||
bool operator()
|
||||
(const std::pair<SharedHandle<ServerStat>, std::string> lhs,
|
||||
const std::pair<SharedHandle<ServerStat>, std::string> rhs) const
|
||||
{
|
||||
return lhs.first->getDownloadSpeed() > rhs.first->getDownloadSpeed();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
||||
#endif // D_SERVER_STAT_H
|
||||
|
|
Loading…
Reference in New Issue