aboutsummaryrefslogtreecommitdiff
path: root/discord/backoff.py
diff options
context:
space:
mode:
authorRapptz <[email protected]>2017-02-15 19:07:47 -0500
committerRapptz <[email protected]>2017-02-15 19:10:32 -0500
commit58fa5fdc9acc34661a5ceccd86a5aa23a2b2f897 (patch)
tree9aeb5b18809ffe8e956ed0fdf89e9d44e0c297a4 /discord/backoff.py
parentDon't RESUME when given sharding related close codes. (diff)
downloaddiscord.py-58fa5fdc9acc34661a5ceccd86a5aa23a2b2f897.tar.xz
discord.py-58fa5fdc9acc34661a5ceccd86a5aa23a2b2f897.zip
Add experimental reconnection logic.
Diffstat (limited to 'discord/backoff.py')
-rw-r--r--discord/backoff.py85
1 files changed, 85 insertions, 0 deletions
diff --git a/discord/backoff.py b/discord/backoff.py
new file mode 100644
index 00000000..bfe87b17
--- /dev/null
+++ b/discord/backoff.py
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+
+"""
+The MIT License (MIT)
+
+Copyright (c) 2015-2017 Rapptz
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+"""
+
+import time
+import random
+
+class ExponentialBackoff:
+ """An implementation of the exponential backoff algorithm
+
+ Provides a convenient interface to implement an exponential backoff
+ for reconnecting or retrying transmissions in a distributed network.
+
+ Once instantiated, the delay method will return the next interval to
+ wait for when retrying a connection or transmission. The maximum
+ delay increases exponentially with each retry up to a maximum of
+ 2^10 * base, and is reset if no more attempts are needed in a period
+ of 2^11 * base seconds.
+
+ Parameters
+ ----------
+ base: int
+ The base delay in seconds. The first retry-delay will be up to
+ this many seconds.
+ integral: bool
+ Set to True if whole periods of base is desirable, otherwise any
+ number in between may be returned.
+ """
+
+ def __init__(self, base=1, *, integral=False):
+ self._base = base
+
+ self._exp = 0
+ self._max = 10
+ self._reset_time = base * 2 ** 11
+ self._last_invocation = time.monotonic()
+
+ # Use our own random instance to avoid messing with global one
+ rand = random.Random()
+ rand.seed()
+
+ self._randfunc = rand.rand_range if integral else rand.uniform
+
+ def delay(self):
+ """Compute the next delay
+
+ Returns the next delay to wait according to the exponential
+ backoff algorithm. This is a value between 0 and base * 2^exp
+ where exponent starts off at 1 and is incremented at every
+ invocation of this method up to a maximum of 10.
+
+ If a period of more than base * 2^11 has passed since the last
+ retry, the exponent is reset to 1.
+ """
+ invocation = time.monotonic()
+ interval = invocation - self._last_invocation
+ self._last_invocation = invocation
+
+ if interval > self._reset_time:
+ self._exp = 0
+
+ self._exp = min(self._exp + 1, self._max)
+ return self._randfunc(0, self._base * 2 ** self._exp)