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

How to get master to fork workers from new release? #8

Closed
sandinmyjoints opened this issue Oct 1, 2013 · 1 comment
Closed

How to get master to fork workers from new release? #8

sandinmyjoints opened this issue Oct 1, 2013 · 1 comment

Comments

@sandinmyjoints
Copy link
Contributor

This is more of a conceptual question than an issue with recluster per se, so sorry about that, but any guidance would be appreciated. If I am managing deployment by directories that contain releases, then when I do a new release, how do I tell cluster to fork the new workers from the path to the new release code?

In other words:

Say release A is in /var/deploy/app/A, and symlink /var/deploy/app/current/ points to it. My app lives in app.js so my file argument to recluster is a relative path:
var cluster = recluster("app.js");.

My simple cluster master script lives in cluster.js. I start up a master process via cd /var/deploy/app/A ; node cluster.js which forks a few app.js workers using the code in /var/deploy/app/A. The cwd of the master and the workers is /var/deploy/app/A.

Now I deploy release B to /var/deploy/app/B and update /var/deploy/app/current to point there. I send SIGUSR2 to master. master's cwd is still /var/deploy/app/A, so it is going to fork new workers from there rather than from /var/deploy/app/B.

One solution to this is:

  1. explicitly use the /current symlink when starting the cluster master: cd /var/deploy/app/current ; node /var/deploy/app/current/cluster.js.
  2. specify the file argument to cluster using the symlink from the master process:
var workerPath = process.argv[1].replace("cluster", "app");
var cluster    = recluster(workerPath);

Because the symlink is updated to the new release before SIGUSR2 is sent, the new workers will be forked from the new release.

In practice, I am using Chef and Upstart which complicates things somewhat. But ultimately I want to send a signal to the master process (via service <app name> reload) that will cause it to fork new workers from the new code release that Chef just deposited onto the server. Without the symlink, I haven't thought of a way to keep the same master process around but get it to fork workers from the new code. Do you have any thoughts on this?

@spion
Copy link
Contributor

spion commented Oct 2, 2013

I'm afraid that symlinks are the only way for now. Thats because setupMaster from the cluster module can only be called once.

However, this can probably be worked around by writing a generic worker.js that takes the path to the script from env, then simply require()s it. If we do that, then .reload() could take an optional argument - the path to the new worker module.

But this still won't solve SIGUSR2-based reloads by itself. Your cluster.js will have to ask for configuration (e.g. to open and read a config file - or perhaps to open a unix socket where it can take reload commands). recluster wont do that as it aims to be a minimal library which can be used in any context - but once it supports arguments to cluster.reload this should be easy to implement.

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

2 participants