Esempio n. 1
0
    public function __construct(array $argv)
    {
        PhutilServiceProfiler::getInstance()->enableDiscardMode();
        $original_argv = $argv;
        $args = new PhutilArgumentParser($argv);
        $args->setTagline('daemon overseer');
        $args->setSynopsis(<<<EOHELP
**launch_daemon.php** [__options__] __daemon__
    Launch and oversee an instance of __daemon__.
EOHELP
);
        $args->parseStandardArguments();
        $args->parsePartial(array(array('name' => 'trace-memory', 'help' => 'Enable debug memory tracing.'), array('name' => 'log', 'param' => 'file', 'help' => 'Send output to __file__.'), array('name' => 'daemonize', 'help' => 'Run in the background.'), array('name' => 'phd', 'param' => 'dir', 'help' => 'Write PID information to __dir__.'), array('name' => 'verbose', 'help' => 'Enable verbose activity logging.'), array('name' => 'load-phutil-library', 'param' => 'library', 'repeat' => true, 'help' => 'Load __library__.')));
        $argv = array();
        $more = $args->getUnconsumedArgumentVector();
        $this->daemon = array_shift($more);
        if (!$this->daemon) {
            $args->printHelpAndExit();
        }
        if ($args->getArg('trace')) {
            $this->traceMode = true;
            $argv[] = '--trace';
        }
        if ($args->getArg('trace-memory')) {
            $this->traceMode = true;
            $this->traceMemory = true;
            $argv[] = '--trace-memory';
        }
        if ($args->getArg('load-phutil-library')) {
            foreach ($args->getArg('load-phutil-library') as $library) {
                $argv[] = '--load-phutil-library=' . $library;
            }
        }
        $log = $args->getArg('log');
        if ($log) {
            ini_set('error_log', $log);
            $argv[] = '--log=' . $log;
        }
        $verbose = $args->getArg('verbose');
        if ($verbose) {
            $this->verbose = true;
            $argv[] = '--verbose';
        }
        $this->daemonize = $args->getArg('daemonize');
        $this->phddir = $args->getArg('phd');
        $this->argv = $argv;
        $this->moreArgs = coalesce($more, array());
        error_log("Bringing daemon '{$this->daemon}' online...");
        if (self::$instance) {
            throw new Exception('You may not instantiate more than one Overseer per process.');
        }
        self::$instance = $this;
        if ($this->daemonize) {
            // We need to get rid of these or the daemon will hang when we TERM it
            // waiting for something to read the buffers. TODO: Learn how unix works.
            fclose(STDOUT);
            fclose(STDERR);
            ob_start();
            $pid = pcntl_fork();
            if ($pid === -1) {
                throw new Exception('Unable to fork!');
            } else {
                if ($pid) {
                    exit(0);
                }
            }
        }
        if ($this->phddir) {
            $desc = array('name' => $this->daemon, 'argv' => $this->moreArgs, 'pid' => getmypid(), 'start' => time());
            Filesystem::writeFile($this->phddir . '/daemon.' . getmypid(), json_encode($desc));
        }
        $this->daemonID = $this->generateDaemonID();
        $this->dispatchEvent(self::EVENT_DID_LAUNCH, array('argv' => array_slice($original_argv, 1), 'explicitArgv' => $this->moreArgs));
        declare (ticks=1);
        pcntl_signal(SIGUSR1, array($this, 'didReceiveKeepaliveSignal'));
        pcntl_signal(SIGUSR2, array($this, 'didReceiveNotifySignal'));
        pcntl_signal(SIGINT, array($this, 'didReceiveGracefulSignal'));
        pcntl_signal(SIGTERM, array($this, 'didReceiveTerminalSignal'));
    }
 private function processRogueDaemons($grace_period, $warn, $force_stop)
 {
     $console = PhutilConsole::getConsole();
     $rogue_daemons = PhutilDaemonOverseer::findRunningDaemons();
     if ($rogue_daemons) {
         if ($force_stop) {
             $rogue_pids = ipull($rogue_daemons, 'pid');
             $survivors = $this->sendStopSignals($rogue_pids, $grace_period);
             if ($survivors) {
                 $console->writeErr("%s\n", pht('Unable to stop processes running without PID files. ' . 'Try running this command again with sudo.'));
             }
         } else {
             if ($warn) {
                 $console->writeErr("%s\n", $this->getForceStopHint($rogue_daemons));
             }
         }
     }
     return $rogue_daemons;
 }
    public function __construct(array $argv)
    {
        PhutilServiceProfiler::getInstance()->enableDiscardMode();
        $args = new PhutilArgumentParser($argv);
        $args->setTagline(pht('daemon overseer'));
        $args->setSynopsis(<<<EOHELP
**launch_daemon.php** [__options__] __daemon__
    Launch and oversee an instance of __daemon__.
EOHELP
);
        $args->parseStandardArguments();
        $args->parse(array(array('name' => 'trace-memory', 'help' => pht('Enable debug memory tracing.')), array('name' => 'verbose', 'help' => pht('Enable verbose activity logging.')), array('name' => 'label', 'short' => 'l', 'param' => 'label', 'help' => pht('Optional process label. Makes "%s" nicer, no behavioral effects.', 'ps'))));
        $argv = array();
        if ($args->getArg('trace')) {
            $this->traceMode = true;
            $argv[] = '--trace';
        }
        if ($args->getArg('trace-memory')) {
            $this->traceMode = true;
            $this->traceMemory = true;
            $argv[] = '--trace-memory';
        }
        $verbose = $args->getArg('verbose');
        if ($verbose) {
            $this->verbose = true;
            $argv[] = '--verbose';
        }
        $label = $args->getArg('label');
        if ($label) {
            $argv[] = '-l';
            $argv[] = $label;
        }
        $this->argv = $argv;
        if (function_exists('posix_isatty') && posix_isatty(STDIN)) {
            fprintf(STDERR, pht('Reading daemon configuration from stdin...') . "\n");
        }
        $config = @file_get_contents('php://stdin');
        $config = id(new PhutilJSONParser())->parse($config);
        $this->libraries = idx($config, 'load');
        $this->log = idx($config, 'log');
        $this->daemonize = idx($config, 'daemonize');
        $this->piddir = idx($config, 'piddir');
        $this->config = $config;
        if (self::$instance) {
            throw new Exception(pht('You may not instantiate more than one Overseer per process.'));
        }
        self::$instance = $this;
        $this->startEpoch = time();
        // Check this before we daemonize, since if it's an issue the child will
        // exit immediately.
        if ($this->piddir) {
            $dir = $this->piddir;
            try {
                Filesystem::assertWritable($dir);
            } catch (Exception $ex) {
                throw new Exception(pht("Specified daemon PID directory ('%s') does not exist or is " . "not writable by the daemon user!", $dir));
            }
        }
        if (!idx($config, 'daemons')) {
            throw new PhutilArgumentUsageException(pht('You must specify at least one daemon to start!'));
        }
        if ($this->log) {
            // NOTE: Now that we're committed to daemonizing, redirect the error
            // log if we have a `--log` parameter. Do this at the last moment
            // so as many setup issues as possible are surfaced.
            ini_set('error_log', $this->log);
        }
        if ($this->daemonize) {
            // We need to get rid of these or the daemon will hang when we TERM it
            // waiting for something to read the buffers. TODO: Learn how unix works.
            fclose(STDOUT);
            fclose(STDERR);
            ob_start();
            $pid = pcntl_fork();
            if ($pid === -1) {
                throw new Exception(pht('Unable to fork!'));
            } else {
                if ($pid) {
                    exit(0);
                }
            }
        }
        $this->modules = PhutilDaemonOverseerModule::getAllModules();
        pcntl_signal(SIGUSR2, array($this, 'didReceiveNotifySignal'));
        pcntl_signal(SIGHUP, array($this, 'didReceiveReloadSignal'));
        pcntl_signal(SIGINT, array($this, 'didReceiveGracefulSignal'));
        pcntl_signal(SIGTERM, array($this, 'didReceiveTerminalSignal'));
    }
Esempio n. 4
0
#!/usr/bin/env php
<?php 
declare (ticks=1);
$root = dirname(dirname(dirname(__FILE__)));
require_once $root . '/scripts/__init_script__.php';
$overseer = new PhutilDaemonOverseer($argv);
$overseer->run();
 private function processRogueDaemons($grace_period, $warn, $force_stop)
 {
     $console = PhutilConsole::getConsole();
     $rogue_daemons = PhutilDaemonOverseer::findRunningDaemons();
     if ($rogue_daemons) {
         if ($force_stop) {
             $stop_rogue_daemons = $this->buildRogueDaemons($rogue_daemons);
             $survivors = $this->sendStopSignals($stop_rogue_daemons, $grace_period, $force_stop);
             if ($survivors) {
                 $console->writeErr(pht('Unable to stop processes running without pid files. Try running ' . 'this command again with sudo.' . "\n"));
             }
         } else {
             if ($warn) {
                 $console->writeErr($this->getForceStopHint($rogue_daemons) . "\n");
             }
         }
     }
     return $rogue_daemons;
 }
Esempio n. 6
0
    public function __construct(array $argv)
    {
        PhutilServiceProfiler::getInstance()->enableDiscardMode();
        $original_argv = $argv;
        $args = new PhutilArgumentParser($argv);
        $args->setTagline('daemon overseer');
        $args->setSynopsis(<<<EOHELP
**launch_daemon.php** [__options__] __daemon__
    Launch and oversee an instance of __daemon__.
EOHELP
);
        $args->parsePartial(array(array('name' => 'trace', 'help' => 'Enable debug tracing.'), array('name' => 'trace-memory', 'help' => 'Enable debug memory tracing.'), array('name' => 'log', 'param' => 'file', 'help' => 'Send output to __file__.'), array('name' => 'daemonize', 'help' => 'Run in the background.'), array('name' => 'phd', 'param' => 'dir', 'help' => 'Write PID information to __dir__.'), array('name' => 'conduit-uri', 'param' => 'uri', 'help' => 'Send logs to Conduit on __uri__.'), array('name' => 'verbose', 'help' => 'Enable verbose activity logging.')));
        $argv = $args->getUnconsumedArgumentVector();
        $this->daemon = array_shift($argv);
        if (!$this->daemon) {
            $args->printHelpAndExit();
        }
        if ($args->getArg('trace')) {
            $this->traceMode = true;
            array_unshift($argv, '--trace');
        }
        if ($args->getArg('trace-memory')) {
            $this->traceMode = true;
            $this->traceMemory = true;
            array_unshift($argv, '--trace-memory');
        }
        $log = $args->getArg('log');
        if ($log) {
            ini_set('error_log', $log);
            array_unshift($argv, '--log=' . $log);
        }
        $verbose = $args->getArg('verbose');
        if ($verbose) {
            $this->verbose = true;
            array_unshift($argv, '--verbose');
        }
        $this->daemonize = $args->getArg('daemonize');
        $this->phddir = $args->getArg('phd');
        $this->conduitURI = $args->getArg('conduit-uri');
        $this->argv = $argv;
        error_log("Bringing daemon '{$this->daemon}' online...");
        if (self::$instance) {
            throw new Exception("You may not instantiate more than one Overseer per process.");
        }
        self::$instance = $this;
        if ($this->daemonize) {
            // We need to get rid of these or the daemon will hang when we TERM it
            // waiting for something to read the buffers. TODO: Learn how unix works.
            fclose(STDOUT);
            fclose(STDERR);
            ob_start();
            $pid = pcntl_fork();
            if ($pid === -1) {
                throw new Exception("Unable to fork!");
            } else {
                if ($pid) {
                    exit(0);
                }
            }
        }
        if ($this->phddir) {
            $desc = array('name' => $this->daemon, 'pid' => getmypid(), 'start' => time());
            Filesystem::writeFile($this->phddir . '/daemon.' . getmypid(), json_encode($desc));
        }
        if ($this->conduitURI) {
            $this->conduit = new ConduitClient($this->conduitURI);
            $this->daemonLogID = $this->conduit->callMethodSynchronous('daemon.launched', array('daemon' => $this->daemon, 'host' => php_uname('n'), 'pid' => getmypid(), 'argv' => json_encode(array_slice($original_argv, 1))));
        }
        declare (ticks=1);
        pcntl_signal(SIGUSR1, array($this, 'didReceiveKeepaliveSignal'));
        pcntl_signal(SIGINT, array($this, 'didReceiveTerminalSignal'));
        pcntl_signal(SIGTERM, array($this, 'didReceiveTerminalSignal'));
    }
Esempio n. 7
0
#!/usr/bin/env php
<?php 
// NOTE: This is substantially the same as the libphutil/ "launch_daemon.php"
// script, except it loads the Phabricator environment and adds some Phabricator
// specific flags.
declare (ticks=1);
$root = dirname(dirname(dirname(__FILE__)));
require_once $root . '/scripts/__init_script__.php';
$overseer = new PhutilDaemonOverseer($argv);
$bootloader = PhutilBootloader::getInstance();
foreach ($bootloader->getAllLibraries() as $library) {
    $overseer->addLibrary(phutil_get_library_root($library));
}
$overseer->run();
 public function __construct($daemon, array $argv)
 {
     $this->daemon = $daemon;
     $original_argv = $argv;
     $len = count($argv);
     for ($ii = 1; $ii < $len; $ii++) {
         $matches = null;
         if ($argv[$ii] == '--') {
             break;
         } else {
             if ($argv[$ii] == '--trace') {
                 $this->traceMode = true;
             } else {
                 if ($argv[$ii] == '--trace-memory') {
                     $this->traceMode = true;
                     $this->traceMemory = true;
                 } else {
                     if (preg_match('/^--log=(.*)$/', $argv[$ii], $matches)) {
                         ini_set('error_log', $matches[1]);
                         error_log("Bringing '{$daemon}' online...");
                     } else {
                         if ($argv[$ii] == '--daemonize') {
                             $this->daemonize = true;
                             unset($argv[$ii]);
                         } else {
                             if (preg_match('/^--phd=(.*)$/', $argv[$ii], $matches)) {
                                 $this->phddir = $matches[1];
                                 unset($argv[$ii]);
                             } else {
                                 if (preg_match('/^--conduit-uri=(.*)$/', $argv[$ii], $matches)) {
                                     $this->conduitURI = $matches[1];
                                     unset($argv[$ii]);
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     $this->argv = array_slice($argv, 1);
     if (self::$instance) {
         throw new Exception("You may not instantiate more than one Overseer per process.");
     }
     self::$instance = $this;
     if ($this->daemonize) {
         // We need to get rid of these or the daemon will hang when we TERM it
         // waiting for something to read the buffers. TODO: Learn how unix works.
         fclose(STDOUT);
         fclose(STDERR);
         ob_start();
         $pid = pcntl_fork();
         if ($pid === -1) {
             throw new Exception("Unable to fork!");
         } else {
             if ($pid) {
                 exit(0);
             }
         }
     }
     if ($this->phddir) {
         $desc = array('name' => $this->daemon, 'pid' => getmypid(), 'start' => time());
         Filesystem::writeFile($this->phddir . '/daemon.' . getmypid(), json_encode($desc));
     }
     if ($this->conduitURI) {
         $this->conduit = new ConduitClient($this->conduitURI);
         $this->daemonLogID = $this->conduit->callMethodSynchronous('daemon.launched', array('daemon' => $this->daemon, 'host' => php_uname('n'), 'pid' => getmypid(), 'argv' => json_encode(array_slice($original_argv, 1))));
     }
     declare (ticks=1);
     pcntl_signal(SIGUSR1, array($this, 'didReceiveKeepaliveSignal'));
     pcntl_signal(SIGINT, array($this, 'didReceiveTerminalSignal'));
     pcntl_signal(SIGTERM, array($this, 'didReceiveTerminalSignal'));
 }