Is there a way to terminate / stop a running thread dead in its tracks? Upon launching a rule I would like to know if another instance of that rule is already running and, if it is, I would like to terminate it and continue running the later thread.
My rule summarizes and reports sensor changes. The group of sensors is large and I want to eliminate partial summaries. .lock() forces sequential processing and that is NOT what I want.
Agreed. .lock() forces sequential processing, or as used in the reference example, the later thread does nothing.
Using that method, if .TryLock() finds the lock is available I would like to grab it and execute my code. On the other hand, if .TryLock() finds the lock is NOT available I would like to terminate the previous thread that owns the lock, take the lock, and continue to execute my code.
You can’t. That’s the whole point of a lock, to keep latecomers at bay. I’m not sure what you are trying to do, but it’s just not the right tool for that task.
You’re going to have to construct something with a global flag.
How about a number?
Increment it on rule entry, and remember it in a local variable too.
When you get to the end of the rule, compare local to global counter, if they don’t match throw your results away.
Last rule to bump the counter gets to complete.
There is no way to do this with Rules. However, you could maybe do it with Timers. You would check to see if there is a Timer and if there is cancel it and create a new one. But even there the timing is likely going to get you into trouble assuming these readings are coming in so fast that you have this problem to solve in the first place. Even setting flags and such is going to set up a bunch of race conditions.
Thanks Rich. I was hoping you would reply to my post. I always appreciate reading your responses to us rookies.
I tried the flag method and you are correct about race issues. I have experienced updates coming in bursts of 3 to 5 and some sneaking through the flag.
I suppose I should consider this a no-can-do via a secret command and declare the post closed.
If they come in bursts, can you wait half a second or so after the last one before generating the message? If so, set a timer on the first one to wait. Reschedule the timer on subsequent events. Only after there have been no events for a second or whatever do you generate the report. It’s the basic Design Pattern: Motion Sensor Timer.
Note, you may need to put a lock around the creation/check for the Timer if you are on a particularly fast machine or you might end up with a race condition on the creation of the Timer itself and end up with two or more running at the same time. For those running Scripted Automation, the engine itself will prevent more than one copy of the Rule from running at the same time so a lock is not required.
rossko57 - the referenced link doesn’t go anywhere ( Oops! That page doesn’t exist or is private.). Also, I don’t know when the burst has completed.
Rich - I like the idea of “harvesting” them with the timer, but there can always be yet another update coming. As you suggest a lock can be used to postpone until the current harvest completes.
Another method is to put my rule on a fixed schedule rather than trigger on sensor status update. However this method consumes processor cycles when nothing is happening for long periods of time. As I type this I think your harvest timer approach is superior.
We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%
Those processor cycles consumed are firmly in that 97%. You would never notice the difference even if you were running on something so slow it’s unsupported like an RPi 0w or RPi 1. Your efficiency is worth far more than the computers. Do it the simple way and if triggers the Rule once a minute or once a second and most of the time there’s nothing to do, who cares? You’d probably not be able to measure the difference if you tried.