Exponential backoff in the context of various networking protocols looks something like this:
- When a collision first occurs, send a “Jamming signal” to prevent further data being sent.
- Resend a frame after either 0 seconds or 51.2μs, chosen at random.
- If that fails, resend the frame after either 0s, 51.2μs, 102.4μs, or 153.6μs.
- If that still doesn't work, resend the frame after k · 51.2μs, where k is a random integer between 0 and 23 − 1.
- In general, after the cth failed attempt, resend the frame after k · 51.2μs, where k is a random integer between 0 and 2c − 1.
I've written a generator that handles this:
def exponential_backoff(k): num_failed = 0 while True: suceeded = yield k*random.randint(0, 2**num_failed-1) num_failed = (num_failed + 1) if not suceeded else 0
backoff_generator = exponential_backoff(TIME_FRAME) try: send_message("super cool message") except MessageSendFailed: time.sleep(backoff_generator.send(False)) else: backoff_generator.send(True)
Does this seem like a reasonable way to handle things? The goal was to have a simple method of getting the amount of time to wait, without having to maintain too much state in the application itself, without adding an unreasonable amount of extra processing time, and without too much kruft.