Skip to content

Make backoff account for already-elapsed time. #1712

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 18, 2018

Conversation

mikelehen
Copy link
Contributor

[Port of https://github.com/firebase/firebase-js-sdk/pull/1132]

Note: We actually have a not-yet-used c++ implementation of exponential backoff too. I tried to update it, but it was hard. So I'm punting on that for the moment and will do that in a separate PR later.

Copy link
Contributor

@wilhuff wilhuff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically LGTM

timerID:self.timerID
block:^{
FSTStrongify(self);
self.lastAttemptTime =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If self has become nil the the assignment will nil-dispatch so strictly speaking that's okay, but should we really call the block?

I think this should be:

^{
  FSTStrongify(self);
  if (self) {
    self.lastAttemptTime = [[NSDate date] timeIntervalSince1970];
    block();
  }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable. Fixed.

@mikelehen mikelehen merged commit 4625899 into master Aug 18, 2018
@mikelehen mikelehen deleted the mikelehen/backoff-improvement branch August 18, 2018 02:29
@var-const
Copy link
Contributor

@mikelehen Sorry, only recently noticed this.

We actually have a not-yet-used c++ implementation of exponential backoff too

Can you give an example of when backoff would exhibit incorrect behavior without this change? From a cursory glance, this change seems to protect against clock readjustment. In C++, there are two implementations of the AsyncQueue, one based on C++ standard library and the other on libdispatch. C++ standard library version uses std::chrono::steady_clock, which should not be affected by clock readjustment, so this change might not be necessary. OTOH, I'm not sure about libdispatch behavior here. But perhaps I misunderstand the use case?

@mikelehen
Copy link
Contributor Author

@var-const The goal is to avoid waiting the entire backoff delay if some of it has already elapsed (because we didn't have a reason to reconnect right away).

In particular, imagine:

  1. You do a get() request, which fails because you're offline. We don't reconnect because there are no longer any outstanding listens to send.
  2. 5 minutes later, you do another get() request. When we restart the stream, we should not wait for any backoff delay, since 2 minutes has already gone by since your last attempt.

(similarly if the backoff delay is at 10 seconds, and you wait 6 seconds before initiating a get() that triggers a stream retry, we should only back off for the remaining 4 seconds, rather than wait a full 10 seconds.)

@mikelehen
Copy link
Contributor Author

@var-const Are you looking at porting this? Else, I can. I intentionally skipped the C++ version because I knew it was unused and I suck at C++ and was trying to get this PR in before I went OOO. But I can take a stab at it now unless you're already messing with the C++ backoff implementation.

@var-const
Copy link
Contributor

@mikelehen Ah, thanks for the explanation. I'm not blocked by this, so I'm fine if you port it (and happy to help with C++; current time would be either std::chrono::system_clock::now() (actual system time, subject to clock readjustment) or std::chrono::steady_clock::now() (current time from some underspecified clock which is guaranteed to not be affected by clock readjustment, might be the time since system startup or something like that -- it's good enough for code that only cares about time difference).

@mikelehen
Copy link
Contributor Author

Thanks for the pointers! steady_clock is handy. I sent you a PR: #1787

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants