How to Cancel a Specific Macro Out of Several?

This is a common phenomenon for me.

I use semaphore locks AND I often pause macros. So at a time there could be multiple macros paused or waiting to start executing due to semaphore lock.

Suppose a macro is executing (rest others either paused or locked out due to semaphore) and something goes wrong. May be some file doesn't exist in the folder or click action executed before webpage loaded or any such thing where I need to manually cancel the macro.

I generally use 'cancel all the macros' using a keyboard shortcut. But that makes me loose all those macros as well that were paused or waiting for the execution due to semaphore lock. So then I have to remember and search for the macros that were supposed to get executed next. And then execute them manually.

Is there a way to avoid this?

[P.S. - Just bumped into this Can %ExecutingInstance% token be used here? I used 'display text' action to display what executing instance look like. It is a string of characters and doesn't display the name of macro. If this token can be used here, how to use it? Is knowing apple script a must here? Could not make the sense of the answers here]

Have a look at this post from @peternlewis

2 Likes

The first choice would be to build effective failure contingencies into your macros.

For example:

If file exists do something

Pause until front browser has finished loading

If it comes to it, you can to click the KM menubar icon and manually select a macro to cancel.

%ExecutingInstance% is useful when you want to cancel an instance of a macro programmatically, but that isn't applicable in this case, as you're trying to cancel them ad hoc.

2 Likes

This -- 1000x.

@fluid_eye -- treat each time you have to manually cancel as a chance to improve things. That might be the workflow, getting things in order before the next step is taken. It might be logic -- why have you got so many interdependencies and locks, can you serialise operations with synchronous sub-macros/routines. Or it might be more automated cancellation, using timeouts or "If not whatever then Cancel this macro".

Whenever possible, cancelling macros should be both considered and deliberate so that you don't leave your machine in an "unknown" state -- whether that be folders where some files have been changed but others not, apps in weird situations (dialog box up?) that then block other macros, global variables (if you use them) having unexpected values, etc.

4 Likes

Also ensure there are appropriate timeouts on actions. For the most part, Keyboard Maestro defaults the timeout to 99 hours (essentially infinite), but you should consider and Pause Until or similar actions and set appropriate timeouts.

3 Likes

@Nige_S @peternlewis Agree. I am constantly learning. And community here is supportive. I am grateful for it.

2 Likes

I had come across this but didn't quite catch that but as you specifically suggested it, I tried it again.

It works in my use case.

I'll just have to make sure I set that variable AFTER the pause action or semaphore lock action for every macro.

And I'm going to use this. Thank you.

1 Like

Main reason is I have created a pop up that asks me whether I want to execute the macro or pause it for some time (you can look at it as a snooze for reminder). and I often find myself busy with something and I end up pausing multiple such macros.

Other macros do not require me to carry out any task from my to-do list (these macros are automated. For example, periodically deleting a file) but they are locked out due to semaphore lock as earlier macros (reminders) did not execute.

All these macros are time based. Some of them trigger at specific time of the day or some of them trigger after specific duration since last execution.

Having trouble envisaging this, but it sounds like your workflow is something like:

  • You have "Job A" that needs to be completed before you can delete "File B"
  • You have "Macro A", a reminder to do "Job A" that you snooze until the job is done and is running from the start of the reminder period until job completion
  • You want to "hold" the "Macro B" that deletes "File B" until you have "OK"ed (rather than snoozed) the reminder, completing "Macro A"

What I don't see is why a semaphore is involved in "Macro B". You need it with "Macro A" so you don't spawn multiple instances via your periodic trigger, but "Macro B" could be as simple as

if "Macro A" is not running
   do stuff

...and if "Macro A" is running, "Macro B" will cleanly exit without doing anything. And you can make that as granular as you like:

do some stuff
if "Macro A" is not running
   delete "File B"
   do other cleanup stuff
end if
do other things that do not depend on "Job A" being completed

Semaphore locks are useful, but don't neglect the simpler methods of execution control!

1 Like

I have "Macro A", a reminder to do "Job A" that I snooze if I'm already busy. As the snooze ends, it asks me with the same prompt (if I want to execute now or I'd like to snooze again). At this point, if I am free, I hit execute.
To give you more details, when I hit execute for 'Macro A", it starts and keep on executing until the specified duration completes. Typically, what "Macro A" does is, it simply executes pause action for specified time. This specified time could be 10 mins or 15 mins etc. This time is what I had decided to dedicate for "Job A". During the specified time, I don't want any pop ups from any other macros or I don't want to run any other macros that require user action. After the specified time is over, macro is complete and semaphore lock is unlocked automatically. Allowing next macro to throw its own prompt about whether to execute or to snooze.

Macro B does not require me to execute any task but it does give the same prompt as to execute or to snooze. If I hit execute, then it would go ahead and delete the file. And I want to 'hold' the "Macro B" until "Macro A" finishes.

I'm obviously missing something -- why is "B" a separate macro from "A"? This would appear to be a sequential operation:

  1. Reminder to do something
  2. Eventually do something
  3. Do whatever "B" does

Unless you also have "C", "D", etc that you want to be blocked by "A" but not a pending "B"? In which case, consider using a final action in "A" that "Executes a Macro... B" and setting that action to "Asynchronously" so that "A" completes even while "B" is executing.

I think that what I'm trying (badly!) to find out is "Why are you executing "B" and 'holding' it rather than waiting until you are ready then executing it?" (either as actions within, or as a separate macro triggered by, "A").

1 Like

There are multiple Macros like 'Macro A' and there are multiple macros like 'Macro B'. All macros are independent of each other.

It is possible that 'Macro A' triggers everyday at 1 PM. And Macro B triggers every 18 hours. 18 hours are counted from the point in time when Macro B is FINISHED executing.

I want to manually allow 'Macro B' to execute. I merely want it to TRIGGER automatically. And then when I hit execute, it should go ahead and execute. And Macro B could be of the type that takes away focus (keystrokes and mouse clicks) so that is also another reason why I can't run it simultaneously with 'Macro A.'

Also, to give you additional information, macros like 'Macro A' that trigger at specific time of the day are generally triggered from Apple calendar events (rather than KM feature like cron trigger). As I like have visual sense of what tasks do I have at specific date so that I can avoid overlapping my other plans (For example, offline plans).

So "quite complicated" would be an understatement... :wink:

If you've untangled them as much as you can, you're back back to the original problem of cancelling as few as possible any time you want to clear a "blockage". So concentrate on error-checking and timeouts so your macros can cancel themselves when they have a problem, rather you you having to hit the panic button. That also lets you do any necessary cleanup for each macro as part of the cancellation process.

As well as timeouts, have a look at the Try/Catch action and the ActionResult token -- those, along with If Then Else, will help you handle a huge range of errors within the macro itself.

Broadly speaking, there's two approaches to catching errors:

  1. Look for a wrong thing happening
  2. Look for the right thing not happening

...and you'll find yourself using each, even both, at different points in your macros.

1 Like

:joy: i don't know how much percentage of this statement is humour.
If you feel what I have created is complicated then I would consider myself a good student (studying KM).

Most of my macros consist of keystrokes and clicks. So actions keep on happening and there is no way they'd take more time than necessary. Also, no error pops up.

You misunderstand -- you use actions to ensure correct state (either that something has happened or things are ready for something to happen) and handle the errors appropriately. To use your two examples:

Depending on what you are doing you can explicitly test for its presence with "If... file exists" and cancel if it doesn't, "Pause until... file exists" if you know it'll be there eventually and include a timeout just in case it never appears, "Try/Catch" the action you are performing so that if the operation fails because the file isn't there you can clean up and cancel...

So you "Pause until..." the webpage has loaded or, for "multi-loading" pages, "Pause until..." a certain condition is met such as an image/button on the page has loaded. Again, you can use a timeout for those times your network or the server is down to handle the "it never loads" situations.

There's no need to think of all the possible errors before you start using your macro -- each time you have to manually cancel it, go back to the macro and add the appropriate error handling. The next-best thing to a totally robust macro is one that fails gracefully, maybe with a notification and ideally leaving your system in a known "good" state without you having to intervene.

2 Likes

Amazing

Thank you so much for giving me these insights and showing me the right path. I'll do this :+1:

See you in other threads as I come up with more questions :smile: I have a long way to go it seems.

I was merely happy with being able to automate stuff. But that was just the half part it seems. Error handling is a whole new chapter.