asynchronous processes and variables and errors

Lets see example

var global gV;

function classA_setThemeParams(colour)

{

  gV= col;

  ....

}

function onLayout(dc)

{

classA_setThemeParams();

}

function onUpdate(dc)

{

for(i...)

{

    //something external fe. backgroung call classA_setThemeParams during the loop

    drawables(i).draw(dc);//samewher in drawables there is dc.setColor(gV,gV);  <----------------------------------- from time to time error, why?

}

Error Name: Symbol Not Found Error

Error Name: Invalid Value

Why this happen?

gV should be handle an point to  value

this example  show that

- sdk makes "local var" from global instead of taking value from def every time

- during operation = sdk change handle to object

  • Is saving property is "atomic" and when another process call getPropery app response after setProperty.

    But you're calling setProperty() twice? Surely you don't expect two calls of setProperty() to be atomic. I feel like it doesn't matter, because it doesn't look like you need to use setProperty() and getProperty() at all.

    But I'm not an expert at CIQ background processes, so maybe others will have additional insights.

  • There's this forum comment:

    https://forums.garmin.com/developer/connect-iq/f/discussion/171632/background-widget

    The way this works in when your app starts, you register a temporal event.  Say every hour.  Then ever hour, the background runs.

    When it runs, it passes data byway of Background.exit().  Which is seen in onBackgroundData() in the app itself.

    Here's a blog post to get you started: https://developer.garmin.com/index.php/blog/post/guest-post-creating-a-connect-iq-background-service

    And a forum thread about backgrounding in general. (with an example WF.)

    https://forums.garmin.com/developer/connect-iq/f/discussion/5287/very-simple-sample-of-a-watch-face-with-a-background-process

  • of course I don't expect 2 setProperty are atomic! First it's for prevent memory peak, second is "truly".

    But everything depend of system implantation for example

    vieww -> getppp -> VM  -> app ->

    if the "central" point is VM it can serve request  in queue.

    I only ask "how it run" to write code according rules and to no see errors.

    I know this example, first thing is not clear describe:

    onBackgroundData

    is call after onStart() but before getinitialviev

  • of course I don't expect 2 setProperty are atomic! First it's for prevent memory peak, second is "truly".

    Yeah, I get that part.

    I know this example, first thing is not clear describe:

    onBackgroundData

    is call after onStart() but before getinitialviev

    Again I'm not an expert, but it seems like onBackgroundData() can be called any time after onStart(). (Including before or after getInitialView())

    Jim posted a log of his onBackgroundData() calls in the thread:

    forums.garmin.com/.../1037271

    Would you agree that if onBackgroundData() runs in the main process and not the background process, then getProperty() and setProperty() are unnecessary?

    Maybe I'm missing something though.

    For example, the SDK has the BackgroundTimerApp sample. onBackgroundData accesses the timer view (if it exists), or it sets a member variable. It doesn't use setProperty()

        function onBackgroundData(data) {
            if( mTimerView ) {
                mTimerView.backgroundEvent(data);
            } else {
                mBackgroundData = data;
            }
        }
    
    

    I think this makes it pretty clear that onBackgroundData() runs in the main app (not the background process), but maybe I'm misunderstanding something here.

  • yes, it can be call any time, but when data are waiting because e.g. I'm on activity and see df instead of wf and back to wf it's call before initialview.

    I did as you mention and errors were more often because mTimerView.backgroundEvent(data) was called also by view for example every minutes (or when wf start and I can't check for next oonBackgroundData to initialise view data) so I decieded to save data  onBackgroundData using setPropery and read it in view.

  • So again, I think your question is whether onBackgroundData() can run at the same time as onUpdate()? I don't think it can, but again I am not an expert.

    Like you don't want the getProperty() call to happen in between your two setProperty() calls, right?

    e.g.

    setProperty("foo", null)

    // you don't want getProperty() to happen here

    setProperty("foo", REAL_DATA)

    All I can say is if you are worried about this scenario, then you could use the null check as suggested when you call getProperty.

  • yes, it can be call any time, but when data are waiting because e.g. I'm on activity and see df instead of wf and back to wf it's call before initialview.

    I did as you mention and errors were more often because mTimerView.backgroundEvent(data) was called also by view for example every minutes (or when wf start and I can't check for next oonBackgroundData to initialise view data) so I decieded to save data  onBackgroundData using setPropery and read it in view.

    Right you could use setProperty() to persist the data for when the watchface starts, I get that. But I don't see why you need to call getProperty() anywhere else than onStart().

    In onBackgroundData():

    - if the view is available, set the data in the view

    - if the view is not available, save the data somewhere else (in app class or global variable), and let the view consume the saved data on getInitialView().

    (Similar to the SDK example)

  • because it

    1. produce a lot of code and it consumes memory

    2. it' not a good technique of devolping

    3. when app  called view method I had a lot of strange errors even stack trace "he was starting to stupid" and show me an error in place which not was in trace, so I decided to not call view's method in onBackgroundData but from time to time I have still a strange error

    I've described it flow is:

    1.App.onBackgroundData( which use code:

    /*dictionary

    any_data=

    gps_valid => false,

    gps_lat => null,

    gps_lon => null,

    */

    ....

    //check validation of data

    setProperty(any_key,null);//to protect before peak memory

    setProperty(any_key,any_data);

    ....

    B. In view every second/minutes onUpdate/onPartialUpdate is called asynchronous.

    if(minutes != mMinutes)

    {

    mMinutes = minutes;

    var data = APP.getApp().getPropery(any_key);

    if((data != null) && data[gps_valid])

    {

    // data[gps_lat] and data[gps_lon] should be not null

    //becasuse I check it in  onBackgroundData before setProperty(any_key,any_data);

    // next line generate sometimes rather rarely errors

    //and because rarely I think it's connected with background process

    //which is call every  15 minutes and totally out of my control

    ///Error Name: System Error  or Symbol Not Found Error

    draw(data[gps_lat],data[gps_lon]);//<-------------error

    }

  • my error is strange: there is dictionary in property, when I save it I know that data are "good , complete and consistent" when I read it it's look like some key are from previous data for example I save

    key_1=gps_invalid

    key_2=gps_lat=null

    key_3=gps_lon=null

    when I read using getProperty(I can't using global its' background, there is no view for example, so I have to save data)

    key_1=gps_valid

    key_2=gps_lat=null

    key_3=gps_lon=gps_lon

    This sounds like a bug. If you can recreate it reliably it might be worth reporting.

    You could always try saving your data to 3 separate properties, if you insist on using properties. If you are worried about concurrency (I still have no idea whether onBackgroundData() can run at the same time as onUpdate()), you can try this:

    1) set gps_valid to false

    2) set gps_lat

    3) set gps_lon

    4) set gps_valid to its actual value (true or false)

    Sorry, wish I could be of more help.

  • For me asynchronous processes is normal thing background was made for it, only I want to know rules.

    I can for example not to read data if I wait for response.

    Today I've saved  0.2kb by removing unused tags from layouts so I can write some more code Slight smile