diff -p -up aria2c/src/AbstractCommand.h.pix aria2c/src/AbstractCommand.h --- aria2c/src/AbstractCommand.h.pix 2008-09-18 14:48:03.000000000 +0200 +++ aria2c/src/AbstractCommand.h 2008-10-24 17:33:23.000000000 +0200 @@ -84,8 +84,6 @@ protected: void disableReadCheckSocket(); void disableWriteCheckSocket(); - void setTimeout(time_t timeout) { this->timeout = timeout; } - void prepareForNextAction(Command* nextCommand = 0); void checkIfConnectionEstablished(const SharedHandle<SocketCore>& socket); @@ -105,6 +103,9 @@ private: #endif // ENABLE_ASYNC_DNS public: + + void setTimeout(time_t timeout) { this->timeout = timeout; } + AbstractCommand(int32_t cuid, const SharedHandle<Request>& req, RequestGroup* requestGroup, DownloadEngine* e, const SharedHandle<SocketCore>& s = SharedHandle<SocketCore>()); diff -p -up aria2c/src/AdaptiveURISelector.cc.pix aria2c/src/AdaptiveURISelector.cc --- aria2c/src/AdaptiveURISelector.cc.pix 2008-10-24 11:44:31.000000000 +0200 +++ aria2c/src/AdaptiveURISelector.cc 2008-10-27 14:29:45.000000000 +0100 @@ -66,6 +66,7 @@ AdaptiveURISelector::AdaptiveURISelector _serverStatMan(serverStatMan), _requestGroup(requestGroup), _nbConnections(0), + _custom_timeout(0), _logger(LogFactory::getInstance()) { const Option* op = _requestGroup->getOption(); @@ -76,6 +77,13 @@ AdaptiveURISelector::~AdaptiveURISelecto std::string AdaptiveURISelector::select(std::deque<std::string>& uris, bool reserved) { + _logger->debug("AdaptiveURISelector: called %d\n", _requestGroup->getNumConnection()); + if (uris.empty() && _requestGroup->getNumConnection() <= 1) { + // here we know the download will fail, + // trying to find previously failed uris that may succeed with more permissive values + mayRetryWithIncreasedTimeout(uris); + } + std::string selected = selectOne(uris, reserved); if(selected != A2STR::NIL) @@ -84,9 +92,30 @@ std::string AdaptiveURISelector::select( return selected; } -std::string AdaptiveURISelector::selectOne(std::deque<std::string>& uris, bool reserved) +void AdaptiveURISelector::mayRetryWithIncreasedTimeout(std::deque<std::string>& uris) { + if (_custom_timeout * 2 >= max_timeout) return; + + if (_custom_timeout == 0) + _custom_timeout = _requestGroup->getOption()->getAsInt(PREF_TIMEOUT); + _custom_timeout *= 2; + + // looking for retries + std::deque<std::pair<std::string, DownloadResult::RESULT> > &results = _requestGroup->getResults(); + std::deque<std::pair<std::string, DownloadResult::RESULT> >::iterator result; + loop: + for (result = results.begin(); result != results.end(); result++) { + if (result->second == DownloadResult::TIME_OUT) { + _logger->debug("AdaptiveURISelector: will retry server with increased timeout (%d s): %s", _custom_timeout, result->first.c_str()); + uris.push_back(result->first); + results.erase(result); + goto loop; + } + } +} +std::string AdaptiveURISelector::selectOne(std::deque<std::string>& uris, bool reserved) +{ if(uris.empty()) { return A2STR::NIL; } else { @@ -141,8 +170,15 @@ void AdaptiveURISelector::resetCounters( _nbServerToEvaluate = op->getAsInt(PREF_METALINK_SERVERS) - 1; } +void AdaptiveURISelector::tuneAbstractCommand(std::deque<std::string>& uris, AbstractCommand *command) { + if (_custom_timeout != 0) + command->setTimeout(_custom_timeout); +} + void AdaptiveURISelector::tuneDownloadCommand(std::deque<std::string>& uris, DownloadCommand *command) { adjustLowestSpeedLimit(uris, command); + if (_custom_timeout != 0) + command->setTimeout(_custom_timeout); } void AdaptiveURISelector::adjustLowestSpeedLimit(std::deque<std::string>& uris, DownloadCommand *command) { diff -p -up aria2c/src/AdaptiveURISelector.h.pix aria2c/src/AdaptiveURISelector.h --- aria2c/src/AdaptiveURISelector.h.pix 2008-10-24 11:44:31.000000000 +0200 +++ aria2c/src/AdaptiveURISelector.h 2008-10-27 14:29:58.000000000 +0100 @@ -50,8 +50,12 @@ private: unsigned int _nbServerToEvaluate; unsigned int _nbConnections; + static const unsigned int max_timeout = 60; + unsigned int _custom_timeout; + Logger* _logger; + void mayRetryWithIncreasedTimeout(std::deque<std::string>& uris); std::string selectOne(std::deque<std::string>& uris, bool reserved); void adjustLowestSpeedLimit(std::deque<std::string>& uris, DownloadCommand *command); unsigned int getMaxDownloadSpeed(std::deque<std::string>& uris); @@ -70,6 +74,7 @@ public: virtual std::string select(std::deque<std::string>& uris, bool reserved); virtual void tuneDownloadCommand(std::deque<std::string>& uris, DownloadCommand *command); + virtual void tuneAbstractCommand(std::deque<std::string>& uris, AbstractCommand *command); virtual void resetCounters(); }; diff -p -up aria2c/src/FtpInitiateConnectionCommand.cc.pix aria2c/src/FtpInitiateConnectionCommand.cc --- aria2c/src/FtpInitiateConnectionCommand.cc.pix 2008-09-18 14:48:03.000000000 +0200 +++ aria2c/src/FtpInitiateConnectionCommand.cc 2008-10-27 14:33:16.000000000 +0100 @@ -46,6 +46,7 @@ #include "message.h" #include "prefs.h" #include "HttpConnection.h" +#include "RequestGroup.h" #include "Socket.h" namespace aria2 { @@ -62,7 +63,7 @@ FtpInitiateConnectionCommand::~FtpInitia Command* FtpInitiateConnectionCommand::createNextCommand (const std::deque<std::string>& resolvedAddresses) { - Command* command; + AbstractCommand* command; if(useHTTPProxy()) { logger->info(MSG_CONNECTING_TO_SERVER, cuid, e->option->get(PREF_HTTP_PROXY_HOST).c_str(), @@ -93,6 +94,7 @@ Command* FtpInitiateConnectionCommand::c } else { command = new FtpNegotiationCommand(cuid, req, _requestGroup, e, pooledSocket, FtpNegotiationCommand::SEQ_SEND_CWD); } + _requestGroup->tuneAbstractCommand(command); } return command; } diff -p -up aria2c/src/FtpNegotiationCommand.cc.pix aria2c/src/FtpNegotiationCommand.cc --- aria2c/src/FtpNegotiationCommand.cc.pix 2008-10-27 14:43:24.000000000 +0100 +++ aria2c/src/FtpNegotiationCommand.cc 2008-10-27 17:04:24.000000000 +0100 @@ -118,6 +118,7 @@ bool FtpNegotiationCommand::executeInter bool FtpNegotiationCommand::recvGreeting() { checkIfConnectionEstablished(socket); setTimeout(e->option->getAsInt(PREF_TIMEOUT)); + _requestGroup->tuneAbstractCommand(this); //socket->setBlockingMode(); disableWriteCheckSocket(); setReadCheckSocket(socket); diff -p -up aria2c/src/HttpInitiateConnectionCommand.cc.pix aria2c/src/HttpInitiateConnectionCommand.cc --- aria2c/src/HttpInitiateConnectionCommand.cc.pix 2008-09-18 14:48:03.000000000 +0200 +++ aria2c/src/HttpInitiateConnectionCommand.cc 2008-10-27 16:47:55.000000000 +0100 @@ -41,6 +41,7 @@ #include "HttpRequestCommand.h" #include "HttpProxyRequestCommand.h" #include "DlAbortEx.h" +#include "RequestGroup.h" #include "Option.h" #include "Logger.h" #include "Socket.h" @@ -61,7 +62,7 @@ HttpInitiateConnectionCommand::~HttpInit Command* HttpInitiateConnectionCommand::createNextCommand (const std::deque<std::string>& resolvedAddresses) { - Command* command; + AbstractCommand* command; if(useHTTPProxy()) { logger->info(MSG_CONNECTING_TO_SERVER, cuid, e->option->get(PREF_HTTP_PROXY_HOST).c_str(), @@ -94,6 +95,7 @@ Command* HttpInitiateConnectionCommand:: command = new HttpRequestCommand(cuid, req, _requestGroup, httpConnection, e, socket); } + _requestGroup->tuneAbstractCommand(command); return command; } diff -p -up aria2c/src/RequestGroup.cc.exit-status aria2c/src/RequestGroup.cc --- aria2c/src/RequestGroup.cc.exit-status 2008-10-24 11:44:31.000000000 +0200 +++ aria2c/src/RequestGroup.cc 2008-10-27 11:19:55.000000000 +0100 @@ -509,7 +521,7 @@ void RequestGroup::createNextCommand(std const std::string& method) { std::deque<std::string> pendingURIs; - for(; !_uris.empty() && numCommand--; ) { + for(; numCommand--; ) { std::string uri = _uriSelector->select(_uris, reserved); if(uri.size() == 0) continue; @@ -1066,4 +1076,9 @@ void RequestGroup::tuneDownloadCommand(D _uriSelector->tuneDownloadCommand(_uris, command); } +void RequestGroup::tuneAbstractCommand(AbstractCommand *command) +{ + _uriSelector->tuneAbstractCommand(_uris, command); +} + } // namespace aria2 diff -p -up aria2c/src/RequestGroup.h.exit-status aria2c/src/RequestGroup.h --- aria2c/src/RequestGroup.h.exit-status 2008-10-24 11:44:31.000000000 +0200 +++ aria2c/src/RequestGroup.h 2008-10-27 11:33:39.000000000 +0100 @@ -48,6 +49,7 @@ class DownloadEngine; class SegmentMan; class SegmentManFactory; class Command; +class AbstractCommand; class DownloadCommand; class DownloadContext; class PieceStorage; @@ -375,6 +385,7 @@ public: void increaseAndValidateFileNotFoundCount(); void tuneDownloadCommand(DownloadCommand *command); + void tuneAbstractCommand(AbstractCommand *command); }; typedef SharedHandle<RequestGroup> RequestGroupHandle; diff -p -up aria2c/src/URISelector.h.pix aria2c/src/URISelector.h --- aria2c/src/URISelector.h.pix 2008-10-24 11:44:31.000000000 +0200 +++ aria2c/src/URISelector.h 2008-10-24 18:13:53.000000000 +0200 @@ -41,6 +41,7 @@ namespace aria2 { class DownloadCommand; +class AbstractCommand; class URISelector { public: @@ -49,6 +50,7 @@ public: virtual std::string select(std::deque<std::string>& uris, bool reserved) = 0; virtual void tuneDownloadCommand(std::deque<std::string>& uris, DownloadCommand *command) {}; + virtual void tuneAbstractCommand(std::deque<std::string>& uris, AbstractCommand *command) {}; virtual void resetCounters() { return; }; };