Is there a way to wait for a asynchronous callback and continue with execution after callback is received?

Hi All,

I'm new to Garmin wearable development, so please forgive me possibly wierd question, but I have not found an answer anywhere - Though I was searching a lot.

Thanks for any reply in advance. (Read long story short in bold)

The issue:

I´m creating an app that needs to fetch some json data using makeWebRequest on background - specifically in onTemporalEvent.

Everything is basically working as expected - EXCEPT: 

In my onTemporalEvent Im making a web request which is processed successfully and returns valid data in its callback.

Under certain conditions I want to notify user that there is something new based on the fetched data so I want to call requestApplicationWake from makeWebRequest callback.

In a point of time the data arives and are processedonTemporalEvent is already out of scope (or callback function is not running in a scope of background at all) - therefore requestApplicationWake does not take effect.

if I call requestApplicationWake from onTemporalEvent directly - I will get a prompt. however calls of requestApplicationWake beyond onTemporalEvent lifetime (understand from webRequest callback) executes with NOP.

Is there a way to wait for a web request callback in onTemporalEvent or ensure requestApplicationWake is called within background context anyhow so that requestApplicationWake is sent within onTemporalEvent after web request data are received?

Any possible workaround?

Thanks,

Martin

*(I know the background task lifetime is 30s maximum and that only onTemporalEvent is guaranteed to execute, but not its child processes possibly)

  • I believe what you're doing should work.  Are you seeing this on a device (which and what firmware) or in the sim (which target and which SDK)

    Have you verified that the call to requestApplicationWake is being made when you think it should be?  Maybe just a println at the same time you can see in the sim or a log file on the device.

  • Hi Jim,

    First, thanks for reply ;).

    I'm currently testing with simulation only ...

    Targets are various, but I rely here on following test

    if(Toybox.System has :ServiceDelegate)



    so that in case background is not supported - user is notified.

    SDK is recent eclipse addon as installed week ago (11/2019) (not nearby now - sorry)

    Have you verified that the call to requestApplicationWake is being made when you think it should be?

    >>> If I add System.println to various parts of a code I can strip it to following "pseudo messages in log"

    1. onTemporalEvent begin
    2. makeWebRequest sent
    3. onTemporalEvent end
    4. makeWebRequestCallback begin
    5. requestApplicationWake call
    6. background.exit call
    7. makeWebRequestCallback end

    It takes second or two to process the webRequest (fetch the data) and trigger callback - but makeWebRequest does not block for this time and it seems that background thread just continues seamlesly towards the background thread end and that it does not take into account any child process that was forked and just terminates when it reaches end.

    Any advice?

    Thanks and regards,

    Martin

  • So you are doing the Background.exit() in your callback function?

    This is something I'd try on a real device as soon as you can.

  • Yes, 

    from what I read Background.exit() call is precondition for requestApplicationWake to take place.

    As I'm not nearby my setup I cannot guarantee this (and I will post an update on that once I check this) but in console window using simulator - logs fro web callback are not marked with "background:" so that it is rather like this:

    1. background: onTemporalEvent begin
    2. background: makeWebRequest sent
    3. background: onTemporalEvent end
    4. makeWebRequestCallback begin
    5. requestApplicationWake call
    6. background.exit call
    7. makeWebRequestCallback end

    I verify that once I'm back home. Both - behavior on real device and console outputs.

    Martin

  • Not sure if it worth to mention that I'm not calling makeWebRequestCallback from  onTemporalEvent directly, but I have a wrapper function for it - but I'd expect this should have no impact on result ..

  • This is a more complex case than yours but here's one of my console logs:

    Background: TE do requeest
    Background: comm make call
    Background: comm rec sta
    Background: comm make call
    Background: comm rec wea
    Background: TE in callback

    In onTemporalEvent, I create a class that actually does the request, and it fires off that request, with a callback in the service delegate.  The first call in "comm" is to get a station based on the lat/lon, and the second call is to get weather data for that station.  The "rec wea" callback calls the callback in the service delegate class.

    You'll see all is denoted as background.  The Background.exit() is done in the callback in the service delegate class.

    There's no threading or forking in a background process.  the Background.exit() is the last thing you do, correct?  As that end the backgound.

  • So here is actual console output taken from console after trigger in simulation window temporal event for my app:

    Background: App initialize
    Background: App onStart
    Background: App getServiceDelegate
    Background: Delegate onTemporalEvent begin
    Background: Delegate onTemporalEvent makeWebRequest 
    Background: Delegate onTemporalEvent end
    Background: Delegate onReceiveResponse begin
    Background: Delegate onReceiveResponse responseCode 200
    Background: Delegate onReceiveTriggers requestApplicationWake
    Background: Delegate onReceiveTriggers exit

    Interrestingly on my F5+ it does not work too :/. (FW version 9.10 [df7c02e])

    my SDK is 3.1.6 / October 23:

    and IDE Eclipse Version: 2019-09 R (4.13.0) Build id: 20190917-1200 (Windows 10 Pro x64)

    makeWebRequest just does not block for me :/. Could this be a bug ?

    Martin

  • I've done next to noting with requestApplicationWake, but is it called when your application is already running on the real device?  If so, I'm thinking you wont see the dialog about waking the app as it's already awake.

  • Before temporal event trigger I either navigate back from the applicatin scope or trigger onHide.. but mostly i hit back until there is only garmin triangle on screen in simulator. Same on real device. I switch to watchscreen and count on the scheduled wake up duration - and nothinh happens after those 5mins-which is minumum bg task “period”

  • Do you know the temporal even runs on the actual watch?  Again, use a println and log file on the device.