chrisboulton / php-resque

PHP port of resque (Workers and Queueing)
MIT License
3.43k stars 759 forks source link

Method to cancel a Job #209

Open sooners87 opened 10 years ago

sooners87 commented 10 years ago

Is there a method to cancel the running job? I see using the Resque_Worker can find the worker..But using shutdownNow() did not stop the job running.

sooners87 commented 10 years ago

This is what i am doing now, passing the workerId, which is running $worker = Resque_Worker::find($workerId); $logger = new Resque_Log(true); $worker->setLogger($logger);

Getting all the process ids for the worker $pids = $worker->workerPids();

and then use php exec method to just kill the child process.

but i am thinking the killchild ethod would do the same thing. But i get a error saying there is no child. $worker->killChild();

The Resque_Worker object has a $child variable, but the object that was returned after the find, has no child in it to kill.

danhunsaker commented 10 years ago

That is the purpose of killChild(), yes. However, it's meant to be used via OS signals, as the child PID is only tracked internally and not stored anywhere for use by other code. This is something we might be able to do at some point, though the project maintainer is a very very busy man, so it may be some time before such a change was merged. So I recommend instead sending an OS signal to the actual worker process in question (assuming you can identify which worker PID corresponds to the one you care about; there might be some keys in Redis to help with that) telling it to kill its child. That would have the desired effect without requiring exec().

hardcoder80 commented 10 years ago

You need to make a function that loops and checks if your needed job has been done or your script needs to be stopped, then you call exit function, all the work needs to be done internally not outside of the job.

sooners87 commented 10 years ago

Sending OS signal did not work due to permission issue. Since the resque was running in different user and the user action from GUI was running under different user.

danhunsaker commented 10 years ago

That would potentially cause some issues, yeah. Curious what you're doing to let your exec() kill the child process, in that case...

Depending on why you need to kill the child, you might be able to use hardcoder80's method, too. Essentially, you could have the job itself check a key in Redis periodically, and if it's set, it terminates. Of course if you're trying to clean up stalled jobs, that won't work.

sooners87 commented 10 years ago

using exec has also the same permission issue..temporarily solving issue by writing a script that would give permission only for this process.

danhunsaker commented 10 years ago

Things get even more interesting when your jobs are running on a different machine than your queueing logic.