[2.2.9] singleThreaded option for apps/drivers

This was in release notes but way down, so I figured it deserves a special mention here in Developers section. So... singleThreaded is a boolean option that belongs in app/driver definition, with default value of false, meaning apps/drivers behave the way they always did. If set to true, though, hub runs all methods for a particular instance of app/driver sequentially, one at a time. It will load app/driver instance data (including state) run a method, and save the data (including state) completely before moving on to the next method call. This applies to top level methods only and not to calls made by app/driver methods.

definition ( // apps
  singleThreaded: true
)

metadata { // drivers
  definition (
    singleThreaded: true
  )
}

This feature has less overead than using atomicState. You can think of app/driver method as running in a single transaction, always committed at the end, even if method threw an exception.

8 Likes

Thank you for this additional information.

What happens if multiple threads attempt to interact simultaneously with a singleThreaded app or driver?

This seems like a major simplifying feature for certain drivers with challenging concurrency issues, but I'm wondering how the callers might need to be modified to account for any changes in behavior (need to retry or wait longer and the like).

1 Like

If calls originate from the hub core software, it would line those requests up in a queue and run them one at a time, first in first out.

Good point about the non-singleThreaded callers, those will have their own (non-singleThreaded) execution context, so single threaded logic will not apply to invoked app/driver. It will be just another call. Off the top of my head, I can quickly add a way to check whether something is running in single threaded context or not, but fully implementing a transactional approach for internal calls will require a more careful evaluation.

1 Like

Ok, that makes sense.

What about calls to other methods from the same driver? Imagine an async handler (I assume this originates from the hub core software) that uses a utility method which updates State. Can I assume that singleThreaded behaviors apply to that invocation of the utility method?

A runIn() scheduled method or async handler like parse() are called by the hub, and will run in a single threaded context at that level. Internal invocations of utility methods will occur in whatever context top level method called by the hub happens to be in. In other words, calling an app/driver method from app/driver code does not change the context it runs in.

2 Likes

Download the Hubitat app