/** * Start a process built with \Happen\Emmiters. * * This will block till the event loop is stopped, so should always be the last * call in your script (unless you pass flags to $ev_flags, but that's up to you). * * @param callable $callable The 'main' function to begin the process with. If omitted, it will call 'main'. * @param integer $ev_flags Run flags to pass to \Ev::run(). * @return integer The exit code. */ public static function run($callable = null, $ev_flags = 0) { // Wrap our callable. $callable = new Callback($callable ?: 'main'); // Make our callable run when the event loop kicks off. $_ = new \EvTimer(0, 0, function () use($callable) { $callable(); }); // Run the event loop. \Ev::run($ev_flags); // Event loop stopped gracefully, all done! return 0; }
function __construct($addr, $callback, $type) { //$this->lock_name = 'bps_'.$type.'_lock'; $this->rnum_name = 'bps_srv_' . $type . '_req_num'; $this->type = $type; $this->lp = new EvLoop(Ev::recommendedBackends()); //cy_create_lock($this->lock_name); $this->srv = stream_socket_server($addr, $errno, $error, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN); if (!$this->srv) { // TODO notify father to stop process. cy_log(CYE_ERROR, $addr . ' bind failed, errno ' . $errno . ' error ' . $error); exit; } if (!is_callable($callback)) { cy_log(CYE_ERROR, 'invalid callback function'); exit; } // set block mode stream_set_blocking($this->srv, 1); stream_set_timeout($this->srv, 0, 0.8); $this->callback = $callback; }
function __construct($addr, $callback, $type) { $this->type = $type; $this->addr = $addr; $this->lp = new EvLoop(Ev::recommendedBackends()); $this->callback = $callback; if (!is_callable($callback)) { cy_log(CYE_ERROR, 'invalid callback function'); exit; } $this->srv = stream_socket_server($this->addr, $errno, $error, STREAM_SERVER_BIND); if (!$this->srv) { // TODO notify father to stop process. cy_log(CYE_ERROR, $this->addr . ' bind failed, errno ' . $errno . ' error ' . $error); exit; } /* libev只支持水平触发,而水平触发的多进程模型是会惊群的,但阻塞句柄不会惊群 */ stream_set_blocking($this->srv, 0); stream_set_timeout($this->srv, 0, 0.1); $this->aw = $this->lp->io($this->srv, Ev::READ, array($this, 'process')); $this->tw = $this->lp->timer(0, 1, array($this, 'timer')); }
/** * start crontab and loop */ public function start() { $this->logger->info("crontab start"); $crontab = new Crontab($this->crontab_config, $this->logger); $timer = new \EvPeriodic(0.0, 60.0, null, function ($timer, $revents) use($crontab) { $pid = pcntl_fork(); if ($pid > 0) { return; } elseif ($pid == 0) { $crontab->start(time()); exit; } else { $this->logger->error("could not fork"); exit; } }); $child = new \EvChild(0, false, function ($child, $revents) { pcntl_waitpid($child->rpid, $status); $message = "process exit. pid:" . $child->rpid . ". exit code:" . $child->rstatus; $this->logger->info($message); }); \Ev::run(); $this->logger->info("crontab exit"); }
}); // Create and launch timer firing after 2 seconds repeating each second // until we manually stop it $w2 = new EvTimer(2, 1, function ($w) { echo "is called every second, is launched after 2 seconds\n"; echo "iteration = ", Ev::iteration(), PHP_EOL; // Stop the watcher after 5 iterations Ev::iteration() == 5 and $w->stop(); // Stop the watcher if further calls cause more than 10 iterations Ev::iteration() >= 10 and $w->stop(); }); // Create stopped timer. It will be inactive until we start it ourselves $w_stopped = EvTimer::createStopped(10, 5, function ($w) { echo "Callback of a timer created as stopped\n"; // Stop the watcher after 2 iterations Ev::iteration() >= 2 and $w->stop(); }); // Loop until Ev::stop() is called or all of watchers stop Ev::run(); // Start and look if it works $w_stopped->start(); echo "Run single iteration\n"; Ev::run(Ev::RUN_ONCE); echo "Restart the second watcher and try to handle the same events, but don't block\n"; $w2->again(); Ev::run(Ev::RUN_NOWAIT); $w = new EvTimer(10, 0, function () { }); echo "Running a blocking loop\n"; Ev::run(); echo "END\n";
/** * 事件循环 * @see EventInterface::loop() */ public function loop() { \Ev::run(); }
/** * Stops the event loop, by stopping all the watchers and breaking out of the event loop. */ public function stop() { foreach ($this->watchers as $watcher) { $watcher->stop(); } \Ev::stop(\Ev::BREAK_ALL); }
public function run($useExternalEventLoop = false) { if (true === $useExternalEventLoop) { // Advertise the library we want to control the event loop echo "Declaring external event loop…\n"; $loop = new EventLoop($this); $this->server->setEventLoop($loop); } // Open main socket $this->server->run(); if (true === $useExternalEventLoop) { // Main advantage of external event loop : you can manage other events // Example : $tick = new \EvTimer(0, 1, [$this, 'evTick1s']); \Ev::run(); } }
public function testRun_startsEventLoop() { $iterations = \Ev::iteration(); (new EventLoop())->run(\Ev::RUN_NOWAIT); $this->assertThat(\Ev::iteration(), $this->greaterThan($iterations)); }