If you want to do something in the future but don’t want to wait around for it in your rule (e.g. you have more stuff you want to do after kicking off the timer) or you may want to reschedule when the timer triggers or cancel it based on subsequent events a timer is the appropriate thing to use.
If you want to wait for a bit and block the rest of the rule from executing until you are done waiting then Thread::sleep is what you want to use.
The biggest difference, as @sipvoip describes, is that Thread::sleep blocks the running of the current rule for a certain number of milliseconds and then continues executing the rest of the logic in the rule. A Timer spins up a separate thread which starts executing in the background after the Timer goes off.
Thus, a call to Thread::sleep(1000)
will not return until a second has passed. A call to createTimer(now.plusSeconds(1), [| logInfo("Timer", "My Timer!")]
will exit immediately and continue executing the rule, possibly even exiting the rule. Then when one seconds has passed “My Timer!” will appear in your log.
I will use Thread::sleep
- The amount of time I want to wait is short (seconds)
- I want to execute some code after the sleep (i.e. I’m waiting for something to happen such as Persistence catching up before executing the rest of a rule’s logic)
- I have no plans to change what I do or set another Thread::sleep should the state not be just right after the sleep
I will use a Timer
- The amount of time I want to wait is relatively long (minutes)
- I may want to cancel or reschedule the code based on subsequent events
- I have additional stuff I want to do in a rule after the timer is created that doesn’t need to wait for the timer code to execute
To be honest the vast majority of the time I use a Timer but there are a couple places where I use Thread::sleep. Most notably when using my hack to figure out which is the most recently updated Item in a Group (a hack to figure out which Item in a Group triggered an update but it depends on lastUpdate so I have to wait for Persistence to save the most recent values) or when I have a set sequence of events such as one case where when one of my Raspberry Pis is detected offline I turn off its outlet, sleep for a second, then turn it back on.
Edit: since this posting is getting a lot of attention right now I’ll add that in the year since I’ve written it a new Expire Binding was developed. I highly recommend whereever possible using the Expire binding instead of Timers as it is easier to use and the code is much cleaner and less error prone.