Browse files

Enable CouchDB to manage OS process daemons.

This is a simple feature that allows useres to configure CouchDB
so that it maintains a given OS level process alive. If the process
dies for any reason, CouchDB will restart it. If the process restarts
too often, then CouchDB will mark it has halted and not attempt
to restart it. The default max restart rate is three times in the
last five seconds. These parameters are adjustable.

Commands that are started in this manner will have access to a simple
API over stdio to request configuration parameters or to add log
statements to CouchDB's logs.

To configure an OS process as a CouchDB os_daemon, create a section
in your local.ini like such:

    daemon_name = /path/to/command -with args

This will make CouchDB bring up the command and attempt to keep it
alive. To request a configuration parameter, an os_daemon can write
a simple JSON message to stdout like such:

    ["get", "os_daemons"]\n

which would return:

    {"daemon_name": "/path/to/command -with args"}


    ["get", "os_daemons", "daemon_name"]\n

which would return:

    "/path/to/command -with args"

There's no restriction on what configuration variables are visible.
There's also no method for altering the configuration.

If you would like your OS daemon to be restarted in the event that
the configuration changes, you can send the following messages:

    ["register", $(SECTION)]\n

When anyting in that section changes, your OS process will be
rebooted so it can pick up the new configuration settings. If you
want to listen for changes on a specific key, you can send something

    ["register", $(SECTION), $(KEY)]\n

In this case, CouchDB will only restart your daemon if that exact
section/key pair changes, instead of anything in that entire section.

Logging commands look like:

    ["log", $(JSON_MESSAGE)]\n

Where $(JSON_MESSAGE) is arbitrary JSON data. These messages are
logged at the 'info' level. If you want to log at a different level
you can pass messages like such:

    ["log", $(JSON_MESSAGE), {"level": $(LEVEL)}]\n

Where $(LEVEL) is one of "debug", "info", or "error".

When implementing a daemon process to be managed by CouchDB you
should remember to use a method like checking the parent process
id or if stdin has been closed. These flags can tell you if
your daemon process has been orphaned so you can exit cleanly.

Tests for this new feature are in:


Tests for the ability to control daemons from the config system.
Adding and removing config entries will dynamically bring the
daemons up and down.


These do some simple testsing of fetching values from the config
API's as well as provides a way for managed daemons to report
log messages that will be combined into CouchDB's log files.


Tests for various error conditions when a daemon is started. Errors
tests included files that are not executable, daemons that die
on boot, daemons that die shortly after boot, and daemons that die
but not often enough to be halted.
  • Loading branch information...
davisp committed Sep 25, 2010
1 parent 7bb18fb commit a791356c271857c67872e4013d4efbfb333e19c9
@@ -48,11 +48,6 @@ javascript = %bindir%/%couchjs_command_name% %localbuilddatadir%/server/main.js
reduce_limit = true
os_process_limit = 25
-; enable external as an httpd handler, then link it with commands here.
-; note, this api is still under consideration.
-; [external]
-; mykey = /path/to/mycommand
view_manager={couch_view, start_link, []}
external_manager={couch_external_manager, start_link, []}
@@ -65,6 +60,7 @@ uuids={couch_uuids, start, []}
auth_cache={couch_auth_cache, start_link, []}
rep_db_changes_listener={couch_rep_db_listener, start_link, []}
vhosts={couch_httpd_vhost, start_link, []}
+os_daemons={couch_os_daemons, start_link, []}
/ = {couch_httpd_misc_handlers, handle_welcome_req, <<"Welcome">>}
@@ -103,6 +99,18 @@ _info = {couch_httpd_db, handle_design_info_req}
_rewrite = {couch_httpd_rewrite, handle_rewrite_req}
_update = {couch_httpd_show, handle_doc_update_req}
+; enable external as an httpd handler, then link it with commands here.
+; note, this api is still under consideration.
+; [external]
+; mykey = /path/to/mycommand
+; Here you can setup commands for CouchDB to manage
+; while it is alive. It will attempt to keep each command
+; alive if it exits.
+; [os_daemons]
+; some_daemon_name = /path/to/script -with args
; Known algorithms:
; random - 128 bits of random awesome
@@ -33,6 +33,12 @@
; enable SSL support by uncommenting the following line and supply the PEM's below.
; httpsd = {couch_httpd, start_link, [https]}
+; For any commands listed here, CouchDB will attempt to ensure that
+; the process remains alive while CouchDB runs as well as shut them
+; down when CouchDB exits.
+;foo = /path/to/command -with args
;cert_file = /full/path/to/server_cert.pem
;key_file = /full/path/to/server_key.pem
@@ -56,6 +56,7 @@ source_files = \
couch_key_tree.erl \
couch_log.erl \
couch_native_process.erl \
+ couch_os_daemons.erl \
couch_os_process.erl \
couch_query_servers.erl \
couch_ref_counter.erl \
@@ -116,6 +117,7 @@ compiled_files = \
couch_key_tree.beam \
couch_log.beam \
couch_native_process.beam \
+ couch_os_daemons.beam \
couch_os_process.beam \
couch_query_servers.beam \
couch_ref_counter.beam \
Oops, something went wrong.

0 comments on commit a791356

Please sign in to comment.