Skip to content
This repository has been archived by the owner on Oct 18, 2024. It is now read-only.

Fully update internal state before invoking periodic-timer callback #89

Merged
merged 1 commit into from
Oct 4, 2024

Commits on Oct 4, 2024

  1. Fully update internal state before invoking periodic-timer callback

    Fixes #88.
    
    Currently when a periodic timer's callback gets invoked, its
    `_nextCall` is still the time of the current call, not the next one.
    If the timer callback itself calls `flushTimers` or `elapse`, this
    causes the same timer to immediately get called again.
    
    Fortunately the fix is easy: update `_nextCall` just before invoking
    `_callback`, instead of just after.
    
    ---
    
    To work through why this is a complete fix (and doesn't leave
    further bugs of this kind still to be fixed):
    
    After this fix, the call to the timer's callback is a tail call from
    `FakeTimer._fire`.  Because the call site of `FakeTimer._fire` is
    immediately followed by `flushMicrotasks()`, this means calling
    other `FakeAsync` methods from the timer callback is no different
    from doing so in a subsequent microtask.
    
    Moreover, when running timers from `flushTimers`, if after the
    `flushMicrotasks` call this turns out to be the last timer to run,
    then `flushTimers` will return with no further updates to the state.
    So when the timer callback is invoked (in that case), the whole
    `FakeAsync` state must already be in a state that `flushTimers`
    would have been happy to leave it in.  (And there's no special
    cleanup that it does only after a non-last timer.)
    
    Similarly, when running timers from `elapse` (the only other
    possibility), the only difference from a state that `elapse` would
    be happy to leave things in is that `_elapsingTo` is still set.
    That field affects only `elapse` and `elapseBlocking`; and those
    are both designed to handle being called from within `elapse`.
    gnprice committed Oct 4, 2024
    Configuration menu
    Copy the full SHA
    8acca6d View commit details
    Browse the repository at this point in the history