From aed0fff4ea668de83405a4457fe238cf36c78d8f Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Thu, 4 Sep 2008 14:40:31 -0400 Subject: [PATCH] scripts daemonize themselves darcs-hash:20080904184031-84dde-eba2061f3aa898d0c791ffeb70837f759778c567.gz --- lib/common.php | 4 ++ lib/daemon.php | 117 +++++++++++++++++++++++++++++++++ lib/queuehandler.php | 19 +++++- scripts/ombqueuehandler.php | 6 +- scripts/publicqueuehandler.php | 6 +- scripts/smsqueuehandler.php | 6 +- scripts/xmppconfirmhandler.php | 14 ++-- scripts/xmppdaemon.php | 26 +++++--- scripts/xmppqueuehandler.php | 6 +- 9 files changed, 167 insertions(+), 37 deletions(-) create mode 100644 lib/daemon.php diff --git a/lib/common.php b/lib/common.php index e4c8e9032a..80aab806f3 100644 --- a/lib/common.php +++ b/lib/common.php @@ -94,6 +94,10 @@ $config = 'public' => array()), # JIDs of users who want to receive the public stream 'tag' => array('dropoff' => 864000.0), + 'daemon' => + array('piddir' => '/var/run', + 'user' => false, + 'group' => false) ); $config['db'] = &PEAR::getStaticProperty('DB_DataObject','options'); diff --git a/lib/daemon.php b/lib/daemon.php new file mode 100644 index 0000000000..09144afe73 --- /dev/null +++ b/lib/daemon.php @@ -0,0 +1,117 @@ +. + */ + +if (!defined('LACONICA')) { exit(1); } + +class Daemon { + + function name() { + return NULL; + } + + function background() { + $pid = pcntl_fork(); + if ($pid < 0) { # error + return false; + } else if ($pid > 0) { # parent + common_log(LOG_INFO, "Successfully forked."); + exit(0); + } else { # child + return true; + } + } + + function alreadyRunning() { + + $pidfilename = $this->pidFilename(); + + if (!$pidfilename) { + return false; + } + + if (!file_exists($pidfilename)) { + return false; + } + $contents = file_get_contents($pidfilename); + if (posix_kill(trim($contents),0)) { + return true; + } else { + return false; + } + } + + function writePidFile() { + $pidfilename = $this->pidFilename(); + + if (!$pidfilename) { + return false; + } + + file_put_contents($pidfilename, posix_getpid()); + } + + function clearPidFile() { + $pidfilename = $this->pidFilename(); + unlink($pidfilename); + } + + function pidFilename() { + $piddir = common_config('daemon', 'piddir'); + if (!$piddir) { + return NULL; + } + $name = $this->name(); + if (!$name) { + return NULL; + } + return $piddir . '/' . $name; + } + + function changeUser() { + + if (common_config('daemon', 'user')) { + $user_info = posix_getpwnam(common_config('daemon', 'user')); + common_log(LOG_INFO, "Setting user to " . common_config('daemon', 'user')); + posix_setuid($user_info['uid']); + } + + if (common_config('daemon', 'group')) { + $group_info = posix_getgrnam(common_config('daemon', 'group')); + common_log(LOG_INFO, "Setting group to " . common_config('daemon', 'group')); + posix_setgid($group_info['gid']); + } + } + + function runOnce() { + if ($this->alreadyRunning()) { + common_log(LOG_INFO, $this->name() . ' already running. Exiting.'); + exit(0); + } + if ($this->background()) { + $this->writePidFile(); + $this->changeUser(); + $this->run(); + $this->clearPidFile(); + } + } + + function run() { + return true; + } +} diff --git a/lib/queuehandler.php b/lib/queuehandler.php index 3115ea38d2..d673f7f947 100644 --- a/lib/queuehandler.php +++ b/lib/queuehandler.php @@ -19,7 +19,11 @@ define('CLAIM_TIMEOUT', 1200); -class QueueHandler { +if (!defined('LACONICA')) { exit(1); } + +require_once(INSTALLDIR.'/lib/daemon.php'); + +class QueueHandler extends Daemon { var $_id = 'generic'; @@ -32,6 +36,10 @@ class QueueHandler { function class_name() { return ucfirst($this->transport()) . 'Handler'; } + + function name() { + return strtolower($this->class_name().'.'.$this->get_id()); + } function get_id() { return $this->_id; @@ -55,7 +63,10 @@ class QueueHandler { return true; } - function handle_queue() { + function run() { + if (!$this->start()) { + return false; + } $this->log(LOG_INFO, 'checking for queued notices'); $transport = $this->transport(); do { @@ -87,6 +98,10 @@ class QueueHandler { $this->idle(5); } } while (true); + if (!$this->finish()) { + return false; + } + return true; } function idle($timeout=0) { diff --git a/scripts/ombqueuehandler.php b/scripts/ombqueuehandler.php index da089feab0..1df816d140 100755 --- a/scripts/ombqueuehandler.php +++ b/scripts/ombqueuehandler.php @@ -71,8 +71,4 @@ $id = ($argc > 1) ? $argv[1] : NULL; $handler = new OmbQueueHandler($id); -if ($handler->start()) { - $handler->handle_queue(); -} - -$handler->finish(); +$handler->runOnce(); diff --git a/scripts/publicqueuehandler.php b/scripts/publicqueuehandler.php index bd0a3670e9..62e60b858f 100755 --- a/scripts/publicqueuehandler.php +++ b/scripts/publicqueuehandler.php @@ -105,8 +105,4 @@ $resource = ($argc > 1) ? $argv[1] : (common_config('xmpp','resource') . '-publi $handler = new PublicQueueHandler($resource); -if ($handler->start()) { - $handler->handle_queue(); -} - -$handler->finish(); +$handler->runOnce(); diff --git a/scripts/smsqueuehandler.php b/scripts/smsqueuehandler.php index 9968a78611..8f0d02d9b6 100755 --- a/scripts/smsqueuehandler.php +++ b/scripts/smsqueuehandler.php @@ -61,8 +61,4 @@ $id = ($argc > 1) ? $argv[1] : NULL; $handler = new SmsQueueHandler($id); -if ($handler->start()) { - $handler->handle_queue(); -} - -$handler->finish(); +$handler->runOnce(); diff --git a/scripts/xmppconfirmhandler.php b/scripts/xmppconfirmhandler.php index e863f3e7ef..3c31c5d8b0 100755 --- a/scripts/xmppconfirmhandler.php +++ b/scripts/xmppconfirmhandler.php @@ -63,7 +63,10 @@ class XmppConfirmHandler { $this->conn->presence(NULL, 'available', NULL, 'available', -1); } - function handle_queue() { + function run() { + if (!$this->start()) { + return false; + } $this->log(LOG_INFO, 'checking for queued confirmations'); do { $confirm = $this->next_confirm(); @@ -99,6 +102,10 @@ class XmppConfirmHandler { $this->idle(10); } } while (true); + if (!$this->finish()) { + return false; + } + return true; } function next_confirm() { @@ -181,8 +188,5 @@ $resource = ($argc > 1) ? $argv[1] : (common_config('xmpp', 'resource').'-confir $handler = new XmppConfirmHandler($resource); -if ($handler->start()) { - $handler->handle_queue(); -} +$handler->runOnce(); -$handler->finish(); diff --git a/scripts/xmppdaemon.php b/scripts/xmppdaemon.php index c29b14b7bd..c5a53e4576 100755 --- a/scripts/xmppdaemon.php +++ b/scripts/xmppdaemon.php @@ -29,6 +29,7 @@ define('LACONICA', true); require_once(INSTALLDIR . '/lib/common.php'); require_once(INSTALLDIR . '/lib/jabber.php'); +require_once(INSTALLDIR . '/lib/daemon.php'); set_error_handler('common_error_handler'); @@ -36,7 +37,7 @@ set_error_handler('common_error_handler'); # in jabber.php, which create a new XMPP class. A more elegant (?) solution # might be to use make this a subclass of XMPP. -class XMPPDaemon { +class XMPPDaemon extends Daemon { function XMPPDaemon($resource=NULL) { static $attrs = array('server', 'port', 'user', 'password', 'host'); @@ -74,12 +75,19 @@ class XMPPDaemon { return !$this->conn->isDisconnected(); } - function handle() { - $this->conn->addEventHandler('message', 'handle_message', $this); - $this->conn->addEventHandler('presence', 'handle_presence', $this); - $this->conn->addEventHandler('reconnect', 'handle_reconnect', $this); - - $this->conn->process(); + function name() { + return strtolower('xmppdaemon.'.$this->resource); + } + + function run() { + if ($this->connect()) { + + $this->conn->addEventHandler('message', 'handle_message', $this); + $this->conn->addEventHandler('presence', 'handle_presence', $this); + $this->conn->addEventHandler('reconnect', 'handle_reconnect', $this); + + $this->conn->process(); + } } function handle_reconnect(&$pl) { @@ -325,6 +333,4 @@ $resource = ($argc > 1) ? $argv[1] : (common_config('xmpp','resource') . '-liste $daemon = new XMPPDaemon($resource); -if ($daemon->connect()) { - $daemon->handle(); -} +$daemon->runOnce(); diff --git a/scripts/xmppqueuehandler.php b/scripts/xmppqueuehandler.php index 4394a1a40e..1c594f210a 100755 --- a/scripts/xmppqueuehandler.php +++ b/scripts/xmppqueuehandler.php @@ -110,8 +110,4 @@ $resource = ($argc > 1) ? $argv[1] : (common_config('xmpp','resource') . '-queue $handler = new XmppQueueHandler($resource); -if ($handler->start()) { - $handler->handle_queue(); -} - -$handler->finish(); +$handler->runOnce(); \ No newline at end of file