Skip to content

Avoid large exponents in BackoffMachine #1339

Open
@PIG208

Description

@PIG208
  Future<void> wait() async {
    final bound = _minDuration(maxBound,
                               firstBound * pow(base, _waitsCompleted));
[ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: Unsupported operation: Infinity or NaN toInt
#0      double.round (dart:core-patch/double.dart)
#1      Duration.* (dart:core/duration.dart:213:56)
#2      BackoffMachine.wait (package:zulip/api/backoff.dart:87:43)
#3      UpdateMachine._registerQueueWithRetry (package:zulip/model/store.dart:930:53)
<asynchronous suspension>
#4      UpdateMachine.load (package:zulip/model/store.dart:875:29)
<asynchronous suspension>
#5      LiveGlobalStore.doLoadPerAccount (package:zulip/model/store.dart:816:27)

What might have happened here is that _waitsCompleted gets to a large enough value that pow(base, _waitsCompleted) becomes either infinity or NaN.

Proposed fix by Greg:

  • Instead of only _waitsCompleted, have also a (private) field equivalent to that bound local.
  • Then at each iteration, multiply that by base and apply _minDuration.
  • That way there's no pow (especially none with a potentially-large argument), and no giant numbers as intermediates in the calculation.

CZO discussion

Metadata

Metadata

Assignees

No one assigned

    Labels

    a-apiImplementing specific parts of the Zulip server APIa-syncEvent queue; retry; local echo; races

    Type

    No type

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions