ably-js icon indicating copy to clipboard operation
ably-js copied to clipboard

React Native warns about setTimeout with long durations when using Ably on Android

Open kj800x opened this issue 6 years ago • 1 comments

Problem Statement:

When subscribing to a channel, React Native warns about setTimeout with long durations when using Ably on Android. React Native will warn about any durations longer than 1 minute (60000 ms).

Setting a timer for a long period of time, i.e. multiple minutes, is a performance and 
correctness issue on Android as it keeps the timer module awake, and timers can only 
be called when the app is in the foreground. 
See https://github.com/facebook/react-native/issues/12981 for more info.
(Saw setTimeout with duration 90000ms)

Reproduceable Example:

  • Clone the reproducable example repo: https://github.com/kj800x/ReactNativeAblyReproducableExample
    • git clone https://github.com/kj800x/ReactNativeAblyReproducableExample
    • cd ReactNativeAblyReproducableExample
  • Install dependencies:
    • npm i
    • react-native link
  • Copy secrets.example.json to secrets.json and insert an api key.
  • Start android emulator
  • Install the new app to the emulator
    • react-native run-android
  • Observe that running the app causes warnings to appear when subscribing to the channel (on startup).

Related:

https://github.com/facebook/react-native/issues/12981

┆Issue is synchronized with this Jira Task by Unito

kj800x avatar Jan 18 '19 19:01 kj800x

Presumably the suspend timeout (120s) and the comet recv timeout (90s).

Really the warning is a red herring, and making changes to avoid it won't actually change the things the warning is worried about: even if we remove the >60s timers there'll at least one <60s one active at all times anyway (when disconnected, the disconnected/suspendedRetryTimer; when connected, the the transport idleTimer).

I don't think the correctness issue it's warning about (timers not getting called when the app is backgrounded) is an issue for ably-js. We don't care about the timer for its own sake, only insofar as it controls the connection & network traffic; and the same mechanism that stops timers firing when an app is backgrounded also stops websocket traffic. So the connection will naturally die if backgrounded for more than ~15s anyway, by the server for not responding to pings, so when next foregrounded (and the timers belatedly fire) it'll disconnect and reconnect. If within the resume period it'll resume, if not it won't. If you need a websocket kept alive even when the app is backgrounded, only way to do that (on android) to put it in a backgound service, AFAIK. (Alternatively, use our mobile push notifications bridge as a fallback when the app is backgrounded)

If you want to suppress the warning, see https://stackoverflow.com/a/48778011

SimonWoolf avatar Jan 18 '19 20:01 SimonWoolf