Exit infinite loop by quitting application - applescript

I have an AppleScript application in which I have a background task running in an infinite loop.
repeat while true
-- do some tasks
delay 0.5
end repeat
When I export and run the application, I am not able to quit it normally, instead I have to use the force quit. How am I able to fix this?

Instead of the infinite loop implement the on idle handler. It allows to consider the quit command.
on idle
-- do some tasks
return 1
end idle
However there is a restriction. The minimum interval is one second.

Related

Can't quit from AppleScript application

I have an endless loop AppleScript application started at login. But there is a problem: I can not quit it unless im using SIGKILL. Is there any way to add some quit handler to it? Or there is better approach to make background process in AppleScript then "repeat - delay - end repeat"?
It doesn't sound like you're using an on idle handler, that's what you want to do.
on run
-- prep code goes here
end run
on idle
-- your code here
display dialog "TEST" giving up after 4
return 10
end idle
The above code will repeat itself every 10 seconds (based on the return value of 10, change as needed). The only other thing to keep in mind is this script needs to be saved as "Stay Open".
Hope this helps

What signal does Intellij use to terminate tests?

I am running some cucumber tests (ruby-based) in Intellij-14 on windows 7. There are times that I want to stop execution of the tests early, but I still want all the cleanup that happens in the cucumber at_exit block to take place. My solution to this was the following code:
trap 'SIGINT' do
cleanup
exit 130
end
It does ensure cleanup takes place upon receiving ctrl+c, but if I am running in Intellij and I stop execution (button is called "stop process"), cleanup does not occur.
What signal does Intellij use to stop running processes? Alternatively, how can I ensure cleanup takes place for every signal?
is there anything preventing you from doing cleanup before the tests? this way you don't have to worry about all signals, and if things are left in an inconsistent state because intellij killed it it's still okay.
Orthogonal to this: http://man7.org/linux/man-pages/man7/signal.7.html
Normally you want to handle: 15 (TERM), 1 (HUP), 2 (INT)

How to use NSAutoreleasePool in AppleScriptObjC

I am wondering how to stop another function from a background function.
In addition, I have to drain NSAutoreleasePool, but I don't know how to do it.
I think this app sometimes freeze if I don't release pool.
property i : 0
property myLabel : missing value
on myStartButtonHandler_(sender)
my performSelectorInBackground_withObject_("start", missing value) -- This code prevents "Stop" Button from freezing.
end myStartButtonHandler_
on myStopButtonHandler_(sender)
-- I want to stop start() function and drain AutoreleasePool!
-- I don't want to use "quit me" because I want to stop only start() function.
end myStopButtonHandler_
on start()
repeat
set i to i + 1
myLabel's setIntegerValue_(i)
delay 1
end repeat
end start
You can download source code from here --> https://dl.dropboxusercontent.com/u/97497395/test2.zip
For your information, I am using Xcode 4.6.3.
EDIT
My script has delay 300 command, so I can't stop the function with checking the value of the variable. Sorry.
EDIT
I conceived of an idea to stop the function while delay commands.
on start()
repeat 5 times
if i = 1 then
error -128
else
delay 60
end repeat
end start
on myStopButtonHandler_(sender)
set i to 1
end myStopButtonHandler_
I can stop the function in 60 seconds, but I can't stop it as soon as I push the stop button. So, I am still waiting for your answer.
An easy way to stop the function is to have a variable. Check the value of the variable. If the variable is true for example then you can exit your repeat loop and drain the autorelease pool. I'm running to work now so no time to write code. Good luck.
EDIT: If you use an NSTimer to fire your handler, as opposed to a repeat loop, then you can invalidate the timer to stop it from running the handler. I use this to invalidate a timer because you should always check that the timer is valid before invalidating it... it will crash if you invalidate a non-valid timer.
-(void)deleteMyTimer {
if ([myTimer isValid]) {
[myTimer invalidate]
myTimer = nil;
}
}

MsWord.BackgroundPrintingStatus

I have an instance of a word document running (opened through a New Word.Application). I have populated the document and sent it to print, however, if i then use the Msword.application.quit method as the next statement it cancels the print job
I have put in a do while MsWord.BackgroundPrintingStatus = 1 loop in but this then goes into an infinite loop.
stepping into the code and giving the print job time to run before continuing to the quit command works fine and the MsWord.BackgroundPrintingStatus does return to 0.
Why would a do while loop go into an infinite loop while waiting for the status to change?
OK found a way to do it. put the quit in a do while printingstatus = 0

Efficient daemon in Vala

i'd like to make a daemon in Vala which only executes a task every X seconds.
I was wondering which would be the best way:
Thread.usleep() or Posix.sleep()
GLib.MainLoop + GLib.Timeout
other?
I don't want it to eat too many resources when it's doing nothing..
If you spend your time sleeping in a system call, there's won't be any appreciable difference from a performance perspective. That said, it probably makes sense to use the MainLoop approach for two reasons:
You're going to need to setup signal handlers so that your daemon can die instantaneously when it is given SIGTERM. If you call quit on your main loop by binding SIGTERM via Posix.signal, that's probably going to be a more readable piece of code than checking that the sleep was successful.
If you ever decide to add complexity, the MainLoop will make it more straight forward.
You can use GLib.Timeout.add_seconds the following way:
Timeout.add_seconds (5000, () => {
/* Do what you want here */
// Continue this "loop" every 5000 ms
return Source.CONTINUE;
// Or remove it
return Source.REMOVE;
}, Priority.LOW);
Note: The Timeout is set as Priority.LOW as it runs in background and should give priority to others tasks.

Resources