Any way to force refresh of State?

smartapp
developers

(Brian) #1

I’ve got some code in a SmartApp that uses a variable stored in State. My problem is that variable gets updated by another process (async call due to using a LAN hubAction callout), yet my code does not seem to be able to recognize the updated variable that gets updated. Is there something I can do to force my code to refresh State and pull the most recent values?

One way of putting it is that I know you can specify “submitOnChange” for Page inputs. I"d like to be able to programmatically kick off whatever gets triggered when an input is changed that has the submitOnChange property.

For more info, my code does something like this:

    def doTheThing(){
      //When this method kicks off, state.myVar = 1
      //Then this method initiates a LAN-based callout
      //This method does a few other things in the meantime
      //The response (async) comes in about this time and is handled separately in the parse method.
      //While processing the response in that other method, state.myVar is set to 2
      //Then, this is executed in this method:

      //Sadly, the below shows state.myVar still equal to 1 instead of 2
      log.debug "state.MyVar is: " + state.myVar
      if (state.myVar == 2){
          DoOtherStuff()
      }
}

Bottom line is that my method is referring to an outdated version of state, and I’d like to be able to force a refresh before grabbing an old value. Any ideas here? I’ve also tried atomicState, but that seemed to make no difference.


(Jim Anderson) #2

No; state is read from external storage when the app starts execution, and written to external storage when finished. If there is overlapping executions, inconsistency can happen.

http://docs.smartthings.com/en/latest/smartapp-developers-guide/state.html#best-practices


(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #3

But what does atomicState do then? Isn’t there Mutex functionality?


(Brian) #4

That’s the big question for me. Seems like atomicState should fix my problem by making it always be current. I do see in that best practices guide that you should never use both state and atomicState in the same SmartApp. I do have other variables where using just State would be fine - is it possible that’s why I’m still having trouble?


(Bruce) #5

Even with atomic state you can be screwed by simultaneous access by two or more processes. There is no protected read-modify-write operation. There is no guarantee as to sequence. If two processes go read-by-a, read-by-b, write-by-a, write-by-b you will have a failure.


(Jim Anderson) #6

The object that backs atomicState will read/write directly to external storage on object access. That’s why it’s recommended to not use it unless you have to, because the external storage read/write (along with any locks the DB layer needs to acquire) is a more expensive operation.


(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #7

Yes… Definitely don’t mix them, IMHO. state is eventually written to the same place as atomicState (I think; @Jim, confirm?, … which could certainly cause more inconsistency).


(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #8

I know that part.

I guess what we need is a mutex lock function… This is a realtime operating system / platform, after all.

There are ways to build mutex if we have at least one atomic method… Dunno. It would be best if inherent in the platform.


(Brian) #9

I just replaced all code in this app to use atomicState. Surprisingly, that seems to have fixed my issue. I now see my updated variable!! :+1:

If mixing the two really was the problem, it might be good to add something to the atomicState documentation saying you won’t get the true benefits from it if you’re still using state for some other variables.


(Alutun) #10

Ok, i do encouter the same kind of error in a device type handler the problem is in the documentation it says :
atomicState is not available to Device Handlers.

but my state is not always the right value or not update well especially in a scope of the parse() function.

so what i learn from the documentation is that if you want to update a state.myvar in the socpe of the parse function (when receiving a z-wave event per exemple).

i need to user the function createEvent

but out of the scope for the same state.myvar if i want to update it let’s say from a GUI user action call from a tile i need to use the following function :

sendEvent

what i can see is that my state.myvar is well update according to my tile but when i passe to the parse() method, the value of the state is not the same.

Any ideas of what’s going on, for me it really look like the same problem describe in this thread


(Eric) #11

Does the documentation state where parallelization occurs in smartapps and device handlers?

Also which library call “create” parallel operation?