At some point, while developing a web-framework with node.js, I thought it would be nice if I could create Daemons in Javascript(no wrappers!). So I've created this very simple module for node.js. It's called daemon.node. Basically, it makes system calls that are required to create a working daemon.
Before I jump in explaining how it works and how to use it, I want to show you how simple it is to create a daemon with this module.
That's it. Just require() the daemon module and call daemon.start(). Of course, it's an oversimplified example, but it is going to produce a working daemon. I'll try to show you more useful examples below.
What is a daemon and how to create it..
Basically, a daemon is a process that runs in the background. I'm not going to talk about Windows daemons(they're called services), but rather focus on traditional *nix daemons.
Without going into the details, in order to become a daemon, a program goes through these steps:
- fork() from a parent process.
- Terminate parent process.
- Create new session with setsid().
This is the minimum requirement for a daemon. If any of these steps fail, the process won't become a daemon.
Now, it is preferred for a daemon to take these additional steps:
- umask() sets file mode creation mask.
- chdir() sets working directory.
- Close stdin, stdout, stderr. The preferred way is to use logging(custom or syslog).
Basically, the daemon.start() function forks, kills parent, creates new session, umasks, chdirs.
In order to close stdin, stdout and stderr, you will have to call daemon.closeIO() function.
By default, umask() is called with the first argument set to 0, and chdir() changes working directory to the root "/". After daemon has been created you can use node's built in functions to alter these settings to your needs: process.umask and process.chdir.
Here's an example:
There's one problem though. How do you know that only one instance of your daemon will be started? The traditional way for this is to use file locks. Daemon creates a file lock. Common convention is to use "/tmp/[daemon_name].lock" or "/var/run/[daemon_name].pid". Then daemon usually writes its own PID to that file, as it can be useful. When daemon terminates it will automatically unlock the file and a new daemon can be started. To create a lock file, you use a module function daemon.lock([filename]). if [filename] doesn't exist, the function creates it automatically.
Example: HTTP-Server daemon.
Here is a complete(well, almost complete) implementation of our hellohttpd.
It's pretty simple and straightforward, so I won't go into explanations here. Now, this example still doesn't implement signal handling. Basically, you would want to handle these two signals SIGHUP and SIGTERM. Many servers use SIGHUP to restart, so it's a good idea to do some serialization, etc. work there. To catch these signals, you should use process.addListener("SIGTERM", function() { ... } );
Hope, you'll find it useful. :)