Cancel All Macros, Except "This One"

:man_facepalming:t2: of course!!

Basically, no.

You can use the ExecutingInstances token, and the Cancel a Specific Macro action, to iterate through all executing macros, and cancel macros except ones that have recorded their ExecutingInstance token somewhere, (and the current macro as well).

So the tools are there for you to write something like this, but I am unlikely to implement an action that cancels all macros except specified macros.

1 Like

That's what I thought until I reviewed the ExecutingInstances token and used a test macro to display the UUIDs of itself and two running test macros.

I have not tested this in depth with a bunch of top-level and sub-macros, but as I read the wiki ExecutingInstances should grab all running macro instances and allow you to process them.

Peter's comments above support my conclusion -- but I wouldn't trust it absolutely without more extensive testing.

1 Like

I should have been clearer -- you can't get a running macro's name or a running macro's UUID except from inside that macro. You can get the UUIDs of all currently executing instances but (AFAIK) there's no simple way to get from instance UUID to macro name/UUID to do "if this instance was created by x theny".

Which leaves us posting the "not to be cancelled" instance UUID in a global then making sure we skip that when cancelling the other %ExecutingInstances% -- see the "Cancel All But..." demo above.

Obvious flaw in the demo is that it only preserves a single instance of any macro. A more comprehensive solution would add instance UUIDs to a list when a "to be kept" macro started and remove them when it finished -- we could then process that list before running the cancellations.

1 Like

I don't have an answer on your specific question, but I did wonder if you could approach this in a different way.

It seems like you never want to cancel your "backup notes" macro. Why then not start the backup in the background by having KM start a script in the background and the immediately finish. You can then cancel all macro's again.

Or is it not feasible to backup your notes from a script?

The backup is actually done via an AppleScript.
Maybe I can create a QuickAction/Service and have KM trigger that and then cancel the macro itself? is that what you are suggesting?

Not really. If you use an AppleScript, you have the option to run the script asynchronously. This means that KM will continue with the next action and if that script execution was the last action it will simply stop the macro while your script continues. If you then kill all macro's it should not kill your AppleScript.

2 Likes

Maybe you could start the AppleScript, quit the KM Engine and then it engine at the end of the script...?

Ultimately though, I think this is the best answer in the thread:

Awesome! That worked like a charm!
I have no idea what "asynchronously" actually does, but yeah, the macro starts and stops immediately, while the script keeps running and all my notes continue backing up!
Thank you so much for this option!

1 Like

@fap's option works great.
@Zabobon's wouldn't work for me... I don't drink coffee... haha

Glad @fap's excellent idea is working for you!

For posterity – one other possible option would be to use an AppleScript applet to run the script.

Keyboard Maestro would tell the applet to run and it would do so just like any other app. The applet would be set to quit on completion of its task and would run completely independently of Keyboard Maestro.

1 Like

You can use ExecutingInstanceName token to get the name of an executing instance.

1 Like

"Asynchronously" is the opposite of "synchronously".

By default things run synchronously which means "in sync", in other words finish one before you start the next task. This is usually what you want because the next step typically depends on the previous step.

Asynchronously however means "in parallel" which means you can not predict in which order things will complete. So if you would start two scripts asynchronously you cannot assume that one completes before the other.

1 Like

D'oh! How did I miss that? That means we don't have to post the "keeper" instance UUID in a global, don't have to worry about multiple instances, etc. Re-write of demo "coming soon".

Is there an advantage to using the name when cancelling? For example, does "Cancel Macro by Name" cancel all instances of that named macro, the most or least recently instantiated, random choice?

Thanks. I was familiar with the definition of asynchronously, but in this case I wasn't sure how this would be related to KM. Now I understand it.

Yes, in most cases in KM you want the next action to wait for the previous one to finish before it starts. And when you don't, asynchronously comes to the rescue.

Much appreciated! :slight_smile:

1 Like

Thank you for that option. I guess this would be similar to a Quick Action/Service, right?
At least, it seems to be the same principle (Applet vs Quick Action/Service), even if it's done differently.

No, there is no option to use the name of the macro in canceling, and there is no “Cancel Macro by Name” action.

Of course there isn't -- where's my head at?

In attempt to make up for that, here's a "Cancel All But..." version that uses a local variable holding macro names, one per line, where you can list the macros you want to stay open. Because it uses names it also handles multiple instances of the same macro, without further work. If you wanted to change the list frequently -- or programmatically -- it would be easy to change Local_toKeepRunning to a global or dictionary.

Plus, and probably a first for me, a sensible (rather than gratuitous!) use of "a variable in a variable" :wink:

Cancel All But... v2.kmmacros (9.0 KB)

Image

3 Likes