How to prevent buildup of macros behind a semaphore lock

I have a semaphore-locked macro running every few seconds and its important that it runs frequently when my computer can handle it. On the other hand, I notice that because of the semaphore lock the debugger will inevitably start to fill up with queued macros since my computer sometimes cannot finish the macro in time. I do not want to slow down the frequency that it runs, rather I want a macro to cancel itself if the semaphore lock has X number of macros waiting for it to open.

I have not tested this, but my thought is to set a KM Variable (that is not deleted) at the beginning of the Macro that increments itself every time the Macro is executed. Then, you could have an IF/THEN Action that cancels the macro if the Execution_Count > X.

You might take a look at this macro, which does something similar:
MACRO: HotKey Multi-Press (Multi-Tap) Template

Basically, it counts the number of hotkey presses (i.e. macro executions) and then takes action accordingly.

You might also take a look at this topic:
How to prevent a timed macro from executing twice at the same time?

1 Like

Good idea, so far the Execution Count variable idea is working. I’m a little worried if I accidentally canceled it at the wrong time that this could cause a bug, but for now, this is ok!

I would be tempted to simply set a silent timeout the Semaphore Lock, so that after it had been waiting for more than a few periods of the trigger frequency that it would abort itself.

1 Like

Peter, that sounds interesting, but I'm not sure I understand it.
Could you please give us some details on how it would work?

For example, when it times out, which instance of the macro is aborted?

How would you design a macro if you wanted all new instances to be canceled if the current instance is still running? IOW, I don't want a backlog that would execute when the current instance completes.

Thanks.

1 Like

Say the trigger frequency is every ten seconds, but the process takes 57 seconds to run.

Set the Semaphore Lock action to time out after 25 seconds, and to abort the macro without notification.

So then we will have:

  • 0:00 Instance 1 triggers and runs
  • 0:10 Instance 2 triggers and blocks (1 blocked)
  • 0:20 Instance 3 triggers and blocks (2 blocked)
  • 0:30 Instance 4 triggers and blocks (3 blocked)
  • 0:35 Instance 2 aborts (2 blocked)
  • 0:40 Instance 5 triggers and blocks (3 blocked)
  • 0:45 Instance 3 aborts (2 blocked)
  • 0:50 Instance 6 triggers and blocks (3 blocked)
  • 0:55 Instance 4 aborts (2 blocked)
  • 0:57 Instance 1 finishes (2 blocked)
  • 0:57 Instance 5 starts (1 blocked)
  • 1:00 Instance 7 triggers and blocks (2 blocked)
  • 1:10 Instance 8 triggers and blocks (3 blocked)
  • 1:15 Instance 4 aborts (2 blocked)
    etc

Set the Semaphore Lock to abort quietly immediately (after a hundredth of a second).

  • 0:00 Instance 1 triggers and runs
  • 0:10 Instance 2 triggers and aborts
  • 0:20 Instance 3 triggers and aborts
  • 0:30 Instance 4 triggers and aborts
  • 0:40 Instance 5 triggers and aborts
  • 0:50 Instance 6 triggers and aborts
  • 0:57 Instance 1 finishes
  • 1:00 Instance 7 triggers and runs
  • 1:10 Instance 8 triggers and aborts
    etc
3 Likes

It's easy to forget about action timeouts, but this solution is perfect. :sunglasses:

1 Like

Perfect for me too. To aid in remembering this, you can either add a Comment Action, or just rename the Semaphore Action:

EDIT: Just to be clear:

This semaphore setup ensures that I never have more than 1 instance of my Macro running, or even waiting to run. As soon as a 2nd instance is triggered, it is canceled/aborted.

My Semaphore Action Setup:

based on @peternlewis' post:

1 Like

Just chiming in to say thanks to all for this- it was exactly the solution I was looking for!