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'));
    }
#!/usr/bin/env php
<?php 
$root = dirname(dirname(dirname(__FILE__)));
require_once $root . '/scripts/__init_script__.php';
$args = new PhutilArgumentParser($argv);
$args->setTagline(pht('emit a test event'));
$args->setSynopsis(<<<EOHELP
**emit_test_event.php** [--listen listener] ...
  Emit a test event after installing any specified __listener__s.
EOHELP
);
$args->parseStandardArguments();
$args->parse(array(array('name' => 'listen', 'param' => 'listener', 'repeat' => true)));
$console = PhutilConsole::getConsole();
foreach ($args->getArg('listen') as $listener) {
    $console->writeOut("%s\n", pht("Installing '%s'...", $listener));
    newv($listener, array())->register();
}
$console->writeOut("%s\n", pht('Emitting event...'));
PhutilEventEngine::dispatchEvent(new PhabricatorEvent(PhabricatorEventType::TYPE_TEST_DIDRUNTEST, array('time' => time())));
$console->writeOut("%s\n", pht('Done.'));
exit(0);
    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'));
    }