diff options
author | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-20 23:55:14 +0000 |
---|---|---|
committer | eroman@chromium.org <eroman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-20 23:55:14 +0000 |
commit | 62df7bb0355940a004564f455f6df63384017826 (patch) | |
tree | 5b6c8e3fe47380d584e31202adf405f7f9e9b397 | |
parent | d634f10e917bb73d42404c5cedb50d99c0b3181c (diff) | |
download | chromium_src-62df7bb0355940a004564f455f6df63384017826.zip chromium_src-62df7bb0355940a004564f455f6df63384017826.tar.gz chromium_src-62df7bb0355940a004564f455f6df63384017826.tar.bz2 |
Decrease the PAC polling delay even further.
Reduces the poll interval for success to 12 hours, and for failures to a maximum of 4 hours.
BUG=110551
Review URL: https://chromiumcodereview.appspot.com/9255033
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118551 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | net/proxy/proxy_service.cc | 91 | ||||
-rw-r--r-- | net/proxy/proxy_service.h | 14 | ||||
-rw-r--r-- | net/proxy/proxy_service_unittest.cc | 64 |
3 files changed, 97 insertions, 72 deletions
diff --git a/net/proxy/proxy_service.cc b/net/proxy/proxy_service.cc index 4660421..ba567c6 100644 --- a/net/proxy/proxy_service.cc +++ b/net/proxy/proxy_service.cc @@ -78,38 +78,74 @@ const int64 kDelayAfterNetworkChangesMs = 2000; // 0: 8 seconds (scheduled on timer) // 1: 32 seconds // 2: 2 minutes -// 3+: 2 hours +// 3+: 4 hours // // In response to a success, the poll intervals are: -// 0: 2 minutes -// 1+: 2 hours +// 0+: 12 hours // // Only the 8 second poll is scheduled on a timer, the rest happen in response // to network activity (and hence will take longer than the written time). +// +// Explanation for these values: +// +// TODO(eroman): These values are somewhat arbitrary, and need to be tuned +// using some histograms data. Trying to be conservative so as not to break +// existing setups when deployed. A simple exponential retry scheme would be +// more elegant, but places more load on server. +// +// The motivation for trying quickly after failures (8 seconds) is to recover +// from spurious network failures, which are common after the IP address has +// just changed (like DNS failing to resolve). The next 32 second boundary is +// to try and catch other VPN weirdness which anecdotally I have seen take +// 10+ seconds for some users. +// +// The motivation for re-trying after a success is to check for possible +// content changes to the script, or to the WPAD auto-discovery results. We are +// not very aggressive with these checks so as to minimize the risk of +// overloading existing PAC setups. Moreover it is unlikely that PAC scripts +// change very frequently in existing setups. More research is needed to +// motivate what safe values are here, and what other user agents do. +// +// Comparison to other browsers: +// +// In Firefox the PAC URL is re-tried on failures according to +// network.proxy.autoconfig_retry_interval_min and +// network.proxy.autoconfig_retry_interval_max. The defaults are 5 seconds and +// 5 minutes respectively. It doubles the interval at each attempt. +// +// TODO(eroman): Figure out what Internet Explorer does. class DefaultPollPolicy : public ProxyService::PacPollPolicy { public: DefaultPollPolicy() {} - virtual Mode GetInitialDelay(int error, int64* next_delay_ms) const OVERRIDE { - // Poll after 8 seconds on errors, versus 2 minutes after a success. - if (error != OK) { - *next_delay_ms = 8000; - return MODE_USE_TIMER; - } - - *next_delay_ms = 120000; - return MODE_START_AFTER_ACTIVITY; - } - - virtual Mode GetNextDelay(int64 current_delay_ms, + virtual Mode GetNextDelay(int initial_error, + int64 current_delay_ms, int64* next_delay_ms) const OVERRIDE { - switch (current_delay_ms) { - case 8000: - *next_delay_ms = 32000; - return MODE_START_AFTER_ACTIVITY; - default: - *next_delay_ms = 7200000; // 2 hours - return MODE_START_AFTER_ACTIVITY; + if (initial_error != OK) { + // Re-try policy for failures. + const int kDelay1 = 8000; // 8 seconds + const int kDelay2 = 32000; // 32 seconds + const int kDelay3 = 120000; // 2 minutes + const int kDelay4 = 14400000; // 4 hours + + switch (current_delay_ms) { + case -1: // Initial poll. + *next_delay_ms = kDelay1; + return MODE_USE_TIMER; + case kDelay1: + *next_delay_ms = kDelay2; + return MODE_START_AFTER_ACTIVITY; + case kDelay2: + *next_delay_ms = kDelay3; + return MODE_START_AFTER_ACTIVITY; + default: + *next_delay_ms = kDelay4; + return MODE_START_AFTER_ACTIVITY; + } + } else { + // Re-try policy for succeses. + *next_delay_ms = 43200000; // 12 hours + return MODE_START_AFTER_ACTIVITY; } } @@ -570,10 +606,9 @@ class ProxyService::ProxyScriptDeciderPoller { last_error_(init_net_error), last_script_data_(init_script_data), last_poll_time_(base::TimeTicks::Now()) { - // Set the initial poll delay -- we check more aggressively right after a - // failure in case it was due to a spurious network error. - next_poll_mode_ = poll_policy()->GetInitialDelay( - init_net_error, &next_poll_delay_ms_); + // Set the initial poll delay. + next_poll_mode_ = poll_policy()->GetNextDelay( + last_error_, -1, &next_poll_delay_ms_); TryToStartNextPoll(false); } @@ -664,8 +699,8 @@ class ProxyService::ProxyScriptDeciderPoller { // Decide when the next poll should take place, and possibly start the // next timer. - next_poll_mode_ = - poll_policy()->GetNextDelay(next_poll_delay_ms_, &next_poll_delay_ms_); + next_poll_mode_ = poll_policy()->GetNextDelay( + last_error_, next_poll_delay_ms_, &next_poll_delay_ms_); TryToStartNextPoll(false); } diff --git a/net/proxy/proxy_service.h b/net/proxy/proxy_service.h index 7fcfa4b..8b657a9 100644 --- a/net/proxy/proxy_service.h +++ b/net/proxy/proxy_service.h @@ -73,14 +73,14 @@ class NET_EXPORT ProxyService : public NetworkChangeNotifier::IPAddressObserver, virtual ~PacPollPolicy() {} - // Decides the initial poll delay. |error| is the network error - // code that the most last PAC fetch failed with (or OK if it was a - // success). Implementations must set |next_delay_ms|. - virtual Mode GetInitialDelay(int error, int64* next_delay_ms) const = 0; - // Decides the next poll delay. |current_delay_ms| is the delay used - // by the preceding poll. Implementations must set |next_delay_ms|. - virtual Mode GetNextDelay(int64 current_delay_ms, + // by the preceding poll, or -1 if determining the delay for the initial + // poll. |initial_error| is the network error code that the last PAC + // fetch (or WPAD initialization) failed with, or OK if it completed + // successfully. Implementations must set |next_delay_ms| to a non-negative + // value. + virtual Mode GetNextDelay(int initial_error, + int64 current_delay_ms, int64* next_delay_ms) const = 0; }; diff --git a/net/proxy/proxy_service_unittest.cc b/net/proxy/proxy_service_unittest.cc index 833c332..2df1725 100644 --- a/net/proxy/proxy_service_unittest.cc +++ b/net/proxy/proxy_service_unittest.cc @@ -33,16 +33,12 @@ class ImmediatePollPolicy : public ProxyService::PacPollPolicy { public: ImmediatePollPolicy() {} - virtual Mode GetInitialDelay(int error, int64* next_delay_ms) const OVERRIDE { + virtual Mode GetNextDelay(int error, int64 current_delay_ms, + int64* next_delay_ms) const OVERRIDE { *next_delay_ms = 1; return MODE_USE_TIMER; } - virtual Mode GetNextDelay(int64 current_delay_ms, - int64* next_delay_ms) const OVERRIDE { - return GetInitialDelay(OK, next_delay_ms); - } - private: DISALLOW_COPY_AND_ASSIGN(ImmediatePollPolicy); }; @@ -53,16 +49,12 @@ class NeverPollPolicy : public ProxyService::PacPollPolicy { public: NeverPollPolicy() {} - virtual Mode GetInitialDelay(int error, int64* next_delay_ms) const OVERRIDE { + virtual Mode GetNextDelay(int error, int64 current_delay_ms, + int64* next_delay_ms) const OVERRIDE { *next_delay_ms = 0xFFFFFFFF; // Big number of milliseconds! return MODE_USE_TIMER; } - virtual Mode GetNextDelay(int64 current_delay_ms, - int64* next_delay_ms) const OVERRIDE { - return GetInitialDelay(OK, next_delay_ms); - } - private: DISALLOW_COPY_AND_ASSIGN(NeverPollPolicy); }; @@ -72,16 +64,12 @@ class ImmediateAfterActivityPollPolicy : public ProxyService::PacPollPolicy { public: ImmediateAfterActivityPollPolicy() {} - virtual Mode GetInitialDelay(int error, int64* next_delay_ms) const OVERRIDE { + virtual Mode GetNextDelay(int error, int64 current_delay_ms, + int64* next_delay_ms) const OVERRIDE { *next_delay_ms = 0; return MODE_START_AFTER_ACTIVITY; } - virtual Mode GetNextDelay(int64 current_delay_ms, - int64* next_delay_ms) const OVERRIDE { - return GetInitialDelay(OK, next_delay_ms); - } - private: DISALLOW_COPY_AND_ASSIGN(ImmediateAfterActivityPollPolicy); }; @@ -2438,56 +2426,58 @@ TEST_F(ProxyServiceTest, PACScriptPollingPolicy) { scoped_ptr<ProxyService::PacPollPolicy> policy = ProxyService::CreateDefaultPacPollPolicy(); + int error; ProxyService::PacPollPolicy::Mode mode; int64 delay_ms = -1; // -------------------------------------------------- // Test the poll sequence in response to a failure. // -------------------------------------------------- - mode = policy->GetInitialDelay(ERR_FAILED, &delay_ms); + error = ERR_NAME_NOT_RESOLVED; + + // Poll #0 + mode = policy->GetNextDelay(error, -1, &delay_ms); EXPECT_EQ(8000, delay_ms); EXPECT_EQ(ProxyService::PacPollPolicy::MODE_USE_TIMER, mode); // Poll #1 - mode = policy->GetNextDelay(delay_ms, &delay_ms); + mode = policy->GetNextDelay(error, delay_ms, &delay_ms); EXPECT_EQ(32000, delay_ms); EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode); // Poll #2 - mode = policy->GetNextDelay(delay_ms, &delay_ms); - EXPECT_EQ(7200000, delay_ms); + mode = policy->GetNextDelay(error, delay_ms, &delay_ms); + EXPECT_EQ(120000, delay_ms); EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode); // Poll #3 - mode = policy->GetNextDelay(delay_ms, &delay_ms); - EXPECT_EQ(7200000, delay_ms); + mode = policy->GetNextDelay(error, delay_ms, &delay_ms); + EXPECT_EQ(14400000, delay_ms); EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode); // Poll #4 - mode = policy->GetNextDelay(delay_ms, &delay_ms); - EXPECT_EQ(7200000, delay_ms); + mode = policy->GetNextDelay(error, delay_ms, &delay_ms); + EXPECT_EQ(14400000, delay_ms); EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode); // -------------------------------------------------- // Test the poll sequence in response to a success. // -------------------------------------------------- - mode = policy->GetInitialDelay(OK, &delay_ms); - EXPECT_EQ(120000, delay_ms); + error = OK; + + // Poll #0 + mode = policy->GetNextDelay(error, -1, &delay_ms); + EXPECT_EQ(43200000, delay_ms); EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode); // Poll #1 - mode = policy->GetNextDelay(delay_ms, &delay_ms); - EXPECT_EQ(7200000, delay_ms); + mode = policy->GetNextDelay(error, delay_ms, &delay_ms); + EXPECT_EQ(43200000, delay_ms); EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode); // Poll #2 - mode = policy->GetNextDelay(delay_ms, &delay_ms); - EXPECT_EQ(7200000, delay_ms); - EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode); - - // Poll #3 - mode = policy->GetNextDelay(delay_ms, &delay_ms); - EXPECT_EQ(7200000, delay_ms); + mode = policy->GetNextDelay(error, delay_ms, &delay_ms); + EXPECT_EQ(43200000, delay_ms); EXPECT_EQ(ProxyService::PacPollPolicy::MODE_START_AFTER_ACTIVITY, mode); } |