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),
|
socketRecvBuffer_(socketRecvBuffer),
|
||||||
checkSocketIsReadable_(false), checkSocketIsWritable_(false),
|
checkSocketIsReadable_(false), checkSocketIsWritable_(false),
|
||||||
nameResolverCheck_(false),
|
nameResolverCheck_(false),
|
||||||
incNumConnection_(incNumConnection)
|
incNumConnection_(incNumConnection),
|
||||||
|
serverStatTimer_(global::wallclock)
|
||||||
{
|
{
|
||||||
if(socket_ && socket_->isOpen()) {
|
if(socket_ && socket_->isOpen()) {
|
||||||
setReadCheckSocket(socket_);
|
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() {
|
bool AbstractCommand::execute() {
|
||||||
A2_LOG_DEBUG(fmt("CUID#%lld - socket: read:%d, write:%d, hup:%d, err:%d",
|
A2_LOG_DEBUG(fmt("CUID#%lld - socket: read:%d, write:%d, hup:%d, err:%d",
|
||||||
getCuid(),
|
getCuid(),
|
||||||
|
@ -158,17 +175,25 @@ bool AbstractCommand::execute() {
|
||||||
!getPieceStorage()->hasMissingUnusedPiece()) {
|
!getPieceStorage()->hasMissingUnusedPiece()) {
|
||||||
SharedHandle<Request> fasterRequest = fileEntry_->findFasterRequest(req_);
|
SharedHandle<Request> fasterRequest = fileEntry_->findFasterRequest(req_);
|
||||||
if(fasterRequest) {
|
if(fasterRequest) {
|
||||||
A2_LOG_INFO(fmt("CUID#%lld - Use faster Request hostname=%s, port=%u",
|
useFasterRequest(fasterRequest);
|
||||||
getCuid(),
|
return true;
|
||||||
fasterRequest->getHost().c_str(),
|
}
|
||||||
fasterRequest->getPort()));
|
}
|
||||||
// Cancel current Request object and use faster one.
|
// Don't use this feature if PREF_MAX_{OVERALL_}DOWNLOAD_LIMIT
|
||||||
fileEntry_->removeRequest(req_);
|
// is used
|
||||||
Command* command =
|
if(e_->getRequestGroupMan()->getMaxOverallDownloadSpeedLimit() == 0 &&
|
||||||
InitiateConnectionCommandFactory::createInitiateConnectionCommand
|
requestGroup_->getMaxDownloadSpeedLimit() == 0 &&
|
||||||
(getCuid(), fasterRequest, fileEntry_, requestGroup_, e_);
|
serverStatTimer_.difference(global::wallclock) >= 10) {
|
||||||
e_->setNoWait(true);
|
serverStatTimer_ = global::wallclock;
|
||||||
e_->addCommand(command);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,9 +85,10 @@ private:
|
||||||
bool nameResolverCheck_;
|
bool nameResolverCheck_;
|
||||||
|
|
||||||
bool incNumConnection_;
|
bool incNumConnection_;
|
||||||
|
Timer serverStatTimer_;
|
||||||
|
|
||||||
size_t calculateMinSplitSize() const;
|
size_t calculateMinSplitSize() const;
|
||||||
|
void useFasterRequest(const SharedHandle<Request>& fasterRequest);
|
||||||
#ifdef ENABLE_ASYNC_DNS
|
#ifdef ENABLE_ASYNC_DNS
|
||||||
void setNameResolverCheck(const SharedHandle<AsyncNameResolver>& resolver);
|
void setNameResolverCheck(const SharedHandle<AsyncNameResolver>& resolver);
|
||||||
|
|
||||||
|
|
|
@ -56,18 +56,6 @@ FeedbackURISelector::FeedbackURISelector
|
||||||
|
|
||||||
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
|
std::string FeedbackURISelector::select
|
||||||
(FileEntry* fileEntry,
|
(FileEntry* fileEntry,
|
||||||
const std::vector<std::pair<size_t, std::string> >& usedHosts)
|
const std::vector<std::pair<size_t, std::string> >& usedHosts)
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
#include "uri.h"
|
#include "uri.h"
|
||||||
#include "PeerStat.h"
|
#include "PeerStat.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
|
#include "ServerStatMan.h"
|
||||||
|
#include "ServerStat.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
|
@ -221,6 +223,57 @@ FileEntry::findFasterRequest(const SharedHandle<Request>& base)
|
||||||
return SharedHandle<Request>();
|
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 {
|
namespace {
|
||||||
class RequestFaster {
|
class RequestFaster {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
|
||||||
class URISelector;
|
class URISelector;
|
||||||
|
class ServerStatMan;
|
||||||
|
|
||||||
class FileEntry {
|
class FileEntry {
|
||||||
private:
|
private:
|
||||||
|
@ -169,6 +170,13 @@ public:
|
||||||
// removed from the pool and returned.
|
// removed from the pool and returned.
|
||||||
SharedHandle<Request> findFasterRequest(const SharedHandle<Request>& base);
|
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);
|
void poolRequest(const SharedHandle<Request>& request);
|
||||||
|
|
||||||
bool removeRequest(const SharedHandle<Request>& request);
|
bool removeRequest(const SharedHandle<Request>& request);
|
||||||
|
|
|
@ -294,6 +294,11 @@ public:
|
||||||
|
|
||||||
// Returns currently used hosts and its use count.
|
// Returns currently used hosts and its use count.
|
||||||
void getUsedHosts(std::vector<std::pair<size_t, std::string> >& usedHosts);
|
void getUsedHosts(std::vector<std::pair<size_t, std::string> >& usedHosts);
|
||||||
|
|
||||||
|
const SharedHandle<ServerStatMan>& getServerStatMan() const
|
||||||
|
{
|
||||||
|
return serverStatMan_;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef SharedHandle<RequestGroupMan> RequestGroupManHandle;
|
typedef SharedHandle<RequestGroupMan> RequestGroupManHandle;
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
||||||
|
#include "SharedHandle.h"
|
||||||
#include "TimeA2.h"
|
#include "TimeA2.h"
|
||||||
|
|
||||||
namespace aria2 {
|
namespace aria2 {
|
||||||
|
@ -167,6 +168,16 @@ private:
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& o, const ServerStat& serverStat);
|
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
|
} // namespace aria2
|
||||||
|
|
||||||
#endif // D_SERVER_STAT_H
|
#endif // D_SERVER_STAT_H
|
||||||
|
|
Loading…
Reference in New Issue