Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
cansozeri opened this issue Mar 23, 2017 · 10 comments
Open

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

cansozeri opened this issue Mar 23, 2017 · 10 comments

Comments

@cansozeri
Copy link

cansozeri commented Mar 23, 2017

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
Copy link
Contributor

danhunsaker commented Mar 23, 2017

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
Copy link
Author

cansozeri commented Mar 23, 2017 via email

@danhunsaker
Copy link
Contributor

danhunsaker commented Mar 23, 2017

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
Copy link

bonndan commented Apr 6, 2017

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link

bonndan commented Apr 7, 2017

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
Copy link
Contributor

danhunsaker commented Apr 7, 2017

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
Copy link

bonndan commented Apr 7, 2017

👍 Much appreciated, thanks.

@arist1213
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants