# Daemonic Daemonic is a tool that let's you turn your long running processes into daemons. At a glance: * Designed to be external to and independent of your app. * Possibility to spawn multiple instances of your app. * Smart restart behavior, comparable to Unicorn. * Automatically restarts crashed instances of your app. ### What can Daemonic do for me? Say you have written your own daemon. It processes messages of a queue for example. You can start it by running `ruby work.rb`. Now the only thing you need to do is turn it into a proper daemon. This means daemonizing your process, managing restarts, adding concurrency, managing a pid file, etc. This is a lot of work, quite error prone and frankly, very tedious. That's where Daemonic comes in. All you need to do, to start your message processor is: ``` $ daemonic --command "ruby work.rb" --pid work.pid --workers 5 --daemonize ``` And voila: you now have 5 instances of your worker, each in it's own process. This works just like Unicorn, but with any kind of process, not just Rack apps. You can restart all workers by sending the `USR2` signal, just like in Unicorn too. ``` $ kill -USR2 `cat work.pid` ``` This will restart each process individually, meaning you never lose capacity. There are some caveats though. For one, daemonic checks if the process is running, but it is very naive. It doesn't really know if the app is ready, just if it is running or not. Secondly, if your app needs a shared resource, spawning multiple workers will not work. This is the case with web servers that need to bind to a port. Also, your own worker needs to respond to the `TERM` and `HUP` signals. Daemonic expects the app to shut down after sending the `TERM` signal. It's up to you to finish up what you are doing. ## Installation You don't need to add daemonic to your Gemfile. You can simply install it and use it straight away. ``` gem install daemonic ``` ## Usage Daemonic accepts command line options and can also read from a configuration file. The configuration file contains the same options as you would pass to the command line. Here is an example: ``` --command "ruby work.rb" --workers 5 --pid tmp/worker.pid --name my-worker --log log/development.log --daemonize ``` Then you can run Daemonic with the `config` option: ``` $ daemonic --config my-worker.conf ``` There are a bunch more options. See `daemonic --help` for the full list. ### Signals These are the signals daemonic responds to: * `TERM`/`INT` shuts down all workers and then the master * `HUP` will be forwarded to each worker and the master will reload the config file * `USR2` will restart each worker, but not the master * `TTIN` increase the number of workers by one * `TTOU` decrease the number of workers by one ### Creating a worker Here's an example of a basic daemonic worker: ``` ruby exiting = false trap("TERM") { exiting = true } trap("INT") { exiting = true } trap("HUP") { # reload settings } puts "Booting worker number #{ENV["DAEMON_WORKER_NUMBER"]}" SomePollingService.poll do # do your work here break if exiting end puts "Shutting down worker number #{ENV["DAEMON_WORKER_NUMBER"]}" ``` Most importantly: * Trap INT and TERM signals to cleanly stop your process ## Contributing 1. Fork it 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) 5. Create new Pull Request ## TODO * Ability to create init script like behavior.