chrisboulton / php-resque

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

I have changed the codes but still the old one is working #332

Open cansozeri opened 7 years ago

cansozeri commented 7 years ago

Hi,

Am I have to restart the workers or something to apply code changes on the job classes ??

Because I have changed some codes on my job class, but still the old one is working ?

Thanx.

danhunsaker commented 7 years ago

So, the forking model of PHP-Resque should usually mean that job classes are only autoloaded after the worker forks, meaning the process that loads the job class should only exist long enough to actually run the job, and the next time that job class is needed, it should be reloaded from disk.

That said, there are a number of reasons this wouldn't be the case, all of them related to the worker trying to find the job class before forking to actually run it. Some are obvious, such as using require/include() or class_exists($job_class, true) in the worker start script, or the script(s) pulled in by the APP_INCLUDE env var. Others are less obvious, and harder to track down. In any case, restarting the workers is generally a good plan anyway when you make code changes.

cansozeri commented 7 years ago

I have restarted the server and the code changes had applied 😊 How can I restart the all workers from command line ?? I can not find any solution about it.

Samsung Mobile tarafından gönderildi.

-------- Orjinal mesaj -------- Kimden: Daniel Hunsaker Tarih:23 03 2017 18:23 (GMT+02:00) Alıcı: chrisboulton/php-resque Cc: cansozeri , Author Konu: Re: [chrisboulton/php-resque] I have changed the codes but still the old one is working (#332)

So, the forking model of PHP-Resque should usually mean that job classes are only autoloaded after the worker forks, meaning the process that loads the job class should only exist long enough to actually run the job, and the next time that job class is needed, it should be reloaded from disk.

That said, there are a number of reasons this wouldn't be the case, all of them related to the worker trying to find the job class before forking to actually run it. Some are obvious, such as using require/include() or class_exists($job_class, true) in the worker start script or APP_INCLUDE env var. Others are less obvious, and harder to track down. In any case, restarting the workers is generally a good plan anyway when you make code changes.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/chrisboulton/php-resque/issues/332#issuecomment-288775522, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AHNLhqYTgtm8EqAu3QFLT8PpEpqfErZrks5ropxngaJpZM4MmtL_.

danhunsaker commented 7 years ago

Assuming you started them using COUNT=, kill the processes (you can look up the PIDs using ps aux), and then re-run the worker start script.

There is at least one fork of this project which keeps the start script alive to manage the actual workers (this version does not do this), but if you were using one of those (or not using COUNT), a simple Ctrl-C would be enough to stop everything so you can restart it.

bonndan commented 7 years ago

Is it a theoretical solution to tell the worker to executed exactly one job and then quit? Would that cause resque to spawn a new worker which reloads the sources? Or is it maybe possible to make the worker quit from inside the job?

danhunsaker commented 7 years ago

That might work on one of the other project forks (such as my own) with the needed patching to actually monitor the workers once they've been started. But.

The actual solution, as stated in my original response, is to ensure none of the job classes are loaded by the worker process before it starts actually doing work. Each job is already run in its own dedicated fork, so any classes the job needs (including the job class itself), that aren't already loaded before work starts, will be pulled directly from the disk in each fork.

danhunsaker commented 7 years ago

It occurs to me, though, that there's one other possible explanation here. If you have a code cache extension such as APC or XCache (etc), make sure you disable it for your workers. At that point (as I understand it), the classes are placed in a location shared by all the PHP processes running at the time, so you have to restart them all (possibly by restarting the entire server) to clear that out. Removing the extension from the CLI's php.ini should be enough, here.

bonndan commented 7 years ago

Thanks for the explanation. Do you have any suggestion for the most foolproof/resilient solution of doing background work in continuous deployment PHP environments?

danhunsaker commented 7 years ago

Sure. Set up your production server so that your worker process is restarted - or better, replaced - with every deploy. I suspect Heroku offers such an option, I know PagodaBox does, and I personally use Nanobox (which, unlike the others, is a toolset, not a platform) these days. It's really the best approach, no matter what queueing engine you select.

As to which engine is best... I really like Resque, but as I'm using Laravel pretty extensively these days, Illuminate\Queue with the Redis driver is my go-to (and works nearly identically, minus some of the more advanced features of Resque's dev-master). Redis is essentially perfect for queueing stuff, since atomicity is built into the design, so any queueing engine that uses it will work really well.

bonndan commented 7 years ago

:+1: Much appreciated, thanks.

arist1213 commented 6 years ago

You can get all resque worker process pid with this command: ps -A -o pid,command | grep "[r]esque"

So you can kill all resque worker process use this command: ps -A -o pid,command|awk '/[r]esque/ FNR > 1 {print $1}' | xargs kill