Move backoff classes to the Zulip API
(imported from commit 76c5d499874f0397c505ab3fcda631a1a46847b6)
This commit is contained in:
parent
ee04f7b3e8
commit
41a782e011
|
@ -28,7 +28,6 @@ import traceback
|
||||||
import signal
|
import signal
|
||||||
|
|
||||||
from zephyr_mirror_backend import parse_args
|
from zephyr_mirror_backend import parse_args
|
||||||
from zephyr_mirror_backend import RandomExponentialBackoff
|
|
||||||
|
|
||||||
def die(signal, frame):
|
def die(signal, frame):
|
||||||
# We actually want to exit, so run os._exit (so as not to be caught and restarted)
|
# We actually want to exit, so run os._exit (so as not to be caught and restarted)
|
||||||
|
@ -38,6 +37,9 @@ signal.signal(signal.SIGINT, die)
|
||||||
|
|
||||||
(options, args) = parse_args()
|
(options, args) = parse_args()
|
||||||
|
|
||||||
|
sys.path[:0] = [os.path.join(options.root_path, 'api')]
|
||||||
|
from zulip import RandomExponentialBackoff
|
||||||
|
|
||||||
args = [os.path.join(options.root_path, "user_root", "zephyr_mirror_backend.py")]
|
args = [os.path.join(options.root_path, "user_root", "zephyr_mirror_backend.py")]
|
||||||
args.extend(sys.argv[1:])
|
args.extend(sys.argv[1:])
|
||||||
|
|
||||||
|
|
|
@ -37,39 +37,8 @@ import signal
|
||||||
import logging
|
import logging
|
||||||
import hashlib
|
import hashlib
|
||||||
import tempfile
|
import tempfile
|
||||||
import random
|
|
||||||
import select
|
import select
|
||||||
|
|
||||||
class CountingBackoff(object):
|
|
||||||
def __init__(self, maximum_retries=10):
|
|
||||||
self.number_of_retries = 0
|
|
||||||
self.maximum_retries = maximum_retries
|
|
||||||
|
|
||||||
def keep_going(self):
|
|
||||||
return self.number_of_retries < self.maximum_retries
|
|
||||||
|
|
||||||
def succeed(self):
|
|
||||||
self.number_of_retries = 0
|
|
||||||
|
|
||||||
def fail(self):
|
|
||||||
self.number_of_retries = min(self.number_of_retries + 1,
|
|
||||||
self.maximum_retries)
|
|
||||||
|
|
||||||
class RandomExponentialBackoff(CountingBackoff):
|
|
||||||
def fail(self):
|
|
||||||
self.number_of_retries = min(self.number_of_retries + 1,
|
|
||||||
self.maximum_retries)
|
|
||||||
# Exponential growth with ratio sqrt(2); compute random delay
|
|
||||||
# between x and 2x where x is growing exponentially
|
|
||||||
delay_scale = int(2 ** (self.number_of_retries / 2.0 - 1)) + 1
|
|
||||||
delay = delay_scale + random.randint(1, delay_scale)
|
|
||||||
message = "Sleeping for %ss [max %s] before retrying." % (delay, delay_scale * 2)
|
|
||||||
try:
|
|
||||||
logger.warning(message)
|
|
||||||
except NameError:
|
|
||||||
print message
|
|
||||||
time.sleep(delay)
|
|
||||||
|
|
||||||
DEFAULT_SITE = "https://api.zulip.com"
|
DEFAULT_SITE = "https://api.zulip.com"
|
||||||
|
|
||||||
class States:
|
class States:
|
||||||
|
@ -478,7 +447,7 @@ def quit_failed_initialization(message):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def zephyr_init_autoretry():
|
def zephyr_init_autoretry():
|
||||||
backoff = RandomExponentialBackoff()
|
backoff = zulip.RandomExponentialBackoff()
|
||||||
while backoff.keep_going():
|
while backoff.keep_going():
|
||||||
try:
|
try:
|
||||||
# zephyr.init() tries to clear old subscriptions, and thus
|
# zephyr.init() tries to clear old subscriptions, and thus
|
||||||
|
@ -493,7 +462,7 @@ def zephyr_init_autoretry():
|
||||||
quit_failed_initialization("Could not initialize Zephyr library, quitting!")
|
quit_failed_initialization("Could not initialize Zephyr library, quitting!")
|
||||||
|
|
||||||
def zephyr_load_session_autoretry(session_path):
|
def zephyr_load_session_autoretry(session_path):
|
||||||
backoff = RandomExponentialBackoff()
|
backoff = zulip.RandomExponentialBackoff()
|
||||||
while backoff.keep_going():
|
while backoff.keep_going():
|
||||||
try:
|
try:
|
||||||
session = file(session_path, "r").read()
|
session = file(session_path, "r").read()
|
||||||
|
@ -508,7 +477,7 @@ def zephyr_load_session_autoretry(session_path):
|
||||||
quit_failed_initialization("Could not load saved Zephyr session, quitting!")
|
quit_failed_initialization("Could not load saved Zephyr session, quitting!")
|
||||||
|
|
||||||
def zephyr_subscribe_autoretry(sub):
|
def zephyr_subscribe_autoretry(sub):
|
||||||
backoff = RandomExponentialBackoff()
|
backoff = zulip.RandomExponentialBackoff()
|
||||||
while backoff.keep_going():
|
while backoff.keep_going():
|
||||||
try:
|
try:
|
||||||
zephyr.Subscriptions().add(sub)
|
zephyr.Subscriptions().add(sub)
|
||||||
|
|
|
@ -30,6 +30,7 @@ import os
|
||||||
import optparse
|
import optparse
|
||||||
import platform
|
import platform
|
||||||
import urllib
|
import urllib
|
||||||
|
import random
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
|
|
||||||
from ConfigParser import SafeConfigParser
|
from ConfigParser import SafeConfigParser
|
||||||
|
@ -46,6 +47,36 @@ requests_json_is_function = callable(requests.Response.json)
|
||||||
|
|
||||||
API_VERSTRING = "v1/"
|
API_VERSTRING = "v1/"
|
||||||
|
|
||||||
|
class CountingBackoff(object):
|
||||||
|
def __init__(self, maximum_retries=10):
|
||||||
|
self.number_of_retries = 0
|
||||||
|
self.maximum_retries = maximum_retries
|
||||||
|
|
||||||
|
def keep_going(self):
|
||||||
|
return self.number_of_retries < self.maximum_retries
|
||||||
|
|
||||||
|
def succeed(self):
|
||||||
|
self.number_of_retries = 0
|
||||||
|
|
||||||
|
def fail(self):
|
||||||
|
self.number_of_retries = min(self.number_of_retries + 1,
|
||||||
|
self.maximum_retries)
|
||||||
|
|
||||||
|
class RandomExponentialBackoff(CountingBackoff):
|
||||||
|
def fail(self):
|
||||||
|
self.number_of_retries = min(self.number_of_retries + 1,
|
||||||
|
self.maximum_retries)
|
||||||
|
# Exponential growth with ratio sqrt(2); compute random delay
|
||||||
|
# between x and 2x where x is growing exponentially
|
||||||
|
delay_scale = int(2 ** (self.number_of_retries / 2.0 - 1)) + 1
|
||||||
|
delay = delay_scale + random.randint(1, delay_scale)
|
||||||
|
message = "Sleeping for %ss [max %s] before retrying." % (delay, delay_scale * 2)
|
||||||
|
try:
|
||||||
|
logger.warning(message)
|
||||||
|
except NameError:
|
||||||
|
print message
|
||||||
|
time.sleep(delay)
|
||||||
|
|
||||||
def _default_client():
|
def _default_client():
|
||||||
return "ZulipPython/" + __version__
|
return "ZulipPython/" + __version__
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue