Closed sandinmyjoints closed 10 years ago
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.
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 myfile
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 thefile
argument to cluster using the symlink from the master process: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?