Watch Face, Background makeWebRequest

Hi,

I have faced with very unexpected behavior when I'm making a web request from a temporal event.
I thought it is a system limitation, that it is impossible to invoke a background delegate frequent than once in 5 min.
But it turns out that on some devices it happens every second or even a bit faster. Simulator and my own device (F5 plus) behave totally fine but in a very rare case, on my users' devices onTemporalEvent() method is invoked as a machinegun.

The background initialization method pretty standard, just as in documentation:


function InitBackgroundEvents()
{
    var FIVE_MINUTES = new Toybox.Time.Duration(5 * 60);
    var lastTime = Background.getLastTemporalEventTime();
    if (lastTime != null)
    {
        var nextTime = lastTime.add(FIVE_MINUTES);
        Background.registerForTemporalEvent(nextTime);
    }
    else
    {
        Background.registerForTemporalEvent(Time.now());
    }
}

And InitBackgroundEvents() being called from two methods:
function getInitialView()
function onSettingChanged()

So, the question. How does it happen that only on a small number of devices temporal event being invoked once in a second and how to avoid this?
Does anybody have the same experience?

  • All you really have to do, is in getInitialView just have this one line, and you don't need anything else in onSettingsChanged, etc:

    //background runs every 5 minutes

    Background.registerForTemporalEvent(new Time.Duration(5 * 60));

    How are you seeing that the background is running every second?  That shouldn't happen under any condition

      

  • I saw that 2 years ago. I am trying to refresh my memory as to when it stopped / or what the issue was.

    I could see my proxy server being spammed by the "machine gun" like triggering of web requests.

  • Wasn't it when there was an error where it wasn't that the the background ran every second but the request was being resent every few seconds due to at error?

  • I had different kind of issues, and the one you mention was one of them, but there also was the issue where I saw requests every 2 seconds hitting my proxy, and that was long before the issue with requests being retried when there was an error. Since then I have spam detection logic in my proxies to prevent requests within 5 minutes from the same device.

    But to be honest, I need to try and find posts to see if I can recall anything.

  • I see how my proxy flooded with requests. And because onTemporalEvent code is very straightforward, the only reasonable explanation is onTemporalEvent being called too often.
    But the error in makeWebRequest implementation also looks as a possible explanation

  • Thanks, HermoT,

    I can also easily handle this on the proxy side, but some of the users are complaining about too fast battery drain. And I guess the reason is too many requests, so better to fix this on the watch side.

  • asn't it when there was an error where it wasn't that the the background ran every second but the request was being resent every few seconds due to at error?

    Is it was an error in the framework or in user code?

  • I don't recall as this was some time ago.

  • You can’t really depend on getLastTemporalEventTime returning a valid value at startup for apps and widgets. This value is reset to null for these app types to allow temporal events to be rescheduled immediately after startup.

    In other words, if your app calls the function you posted above from getInitialView(), it will see a null returned from getLastTemporalEventTime() and schedule the temporal event to run immediately. If you exit the app and start it again, it will see a null returned from getLastTemporalEventTime() and schedule the temporal event to run immediately (again).

    I have a ticket assigned to investigate changing the behavior of getLastTemporaEventTime() to always return a non-null value every time after the first temporal event has completed.

  • The way I got around these issues in the past was to store my own last-run-time and compare to that when I register a temporal event.
    Also I make use of a Moment instead of a duration and have more control over how I register the event.

    Change the logic to check for your own last-run-time and make use of a moment. I'm sure you'll gain better stability / predictability.
    I do still have issues with background web requests, but not as severe as what you've reported and what I've also experienced in the past.