public function run(Promise &$promise) { $urlInfo = parse_url($this->url); $timeout = $this->timeout; if (!isset($urlInfo['port'])) { $urlInfo['port'] = 80; } $cli = new \swoole_http_client($urlInfo['host'], $urlInfo['port']); $cli->set(array('timeout' => $timeout, 'keepalive' => 0)); $cli->on("error", function ($cli) use(&$promise) { Timer::del($cli->sock); $promise->accept(['http_data' => null, 'http_error' => 'Connect error']); }); $cli->on("close", function ($cli) use(&$promise) { }); $cli->execute($this->url, function ($cli) use(&$promise) { Timer::del($cli->sock); $cli->isDone = true; $promise->accept(['http_data' => $cli->body]); }); $cli->isConnected = false; if (!$cli->errCode) { Timer::add($cli->sock, $this->timeout, function () use($cli, &$promise) { @$cli->close(); if ($cli->isConnected) { $promise->accept(['http_data' => null, 'http_error' => 'Http client read timeout']); } else { $promise->accept(['http_data' => null, 'http_error' => 'Http client connect timeout']); } }); } }
/** * Runtime of Master process * @return void */ public function run() { Daemon::$process = $this; $this->prepareSystemEnv(); class_exists('Timer'); // ensure loading this class gc_enable(); $this->eventBase = event_base_new(); $this->registerEventSignals(); FS::initEvent(); $this->fileWatcher = new FileWatcher(); $this->workers = new ThreadCollection(); $this->collections['workers'] = $this->workers; Daemon::$appResolver = (require Daemon::$config->path->value); $this->IPCManager = Daemon::$appResolver->getInstanceByAppName('IPCManager'); Daemon::$appResolver->preload(true); $this->callbacks = new SplStack(); $this->spawnWorkers(min(Daemon::$config->startworkers->value, Daemon::$config->maxworkers->value)); Timer::add(function ($event) use(&$cbs) { $self = Daemon::$process; static $c = 0; ++$c; if ($c > 0xfffff) { $c = 1; } if ($c % 10 == 0) { $self->workers->removeTerminated(true); gc_collect_cycles(); } else { $self->workers->removeTerminated(); } if (isset(Daemon::$config->mpm->value) && is_callable(Daemon::$config->mpm->value)) { call_user_func(Daemon::$config->mpm->value); } else { // default MPM $state = Daemon::getStateOfWorkers($self); if ($state) { $n = max(min(Daemon::$config->minspareworkers->value - $state['idle'], Daemon::$config->maxworkers->value - $state['alive']), Daemon::$config->minworkers->value - $state['alive']); if ($n > 0) { Daemon::log('Spawning ' . $n . ' worker(s).'); $self->spawnWorkers($n); event_base_loopbreak($self->eventBase); } $n = min($state['idle'] - Daemon::$config->maxspareworkers->value, $state['alive'] - Daemon::$config->minworkers->value); if ($n > 0) { Daemon::log('Stopping ' . $n . ' worker(s).'); $self->stopWorkers($n); } } } $event->timeout(); }, 1000000.0 * Daemon::$config->mpmdelay->value, 'MPM'); while (!$this->breakMainLoop) { while (!$this->callbacks->isEmpty()) { call_user_func($this->callbacks->shift(), $this); } event_base_loop($this->eventBase); } }
/** * @param double $timeout */ public function setTimeout($timeout) { if ($timeout !== null) { $this->timer = Timer::add(function () { $this(); }, $timeout); } }
public function run(Promise &$promise) { $cli = new \swoole_client(SWOOLE_TCP, SWOOLE_SOCK_ASYNC); $urlInfo = parse_url($this->url); $timeout = $this->timeout; if (!isset($urlInfo['port'])) { $urlInfo['port'] = 80; } $httpParser = new \HttpParser(); $cli->on("connect", function ($cli) use($urlInfo, &$timeout, &$promise) { $cli->isConnected = true; $host = $urlInfo['host']; if ($urlInfo['port']) { $host .= ':' . $urlInfo['port']; } $req = array(); $req[] = "GET {$this->url} HTTP/1.1\r\n"; $req[] = "User-Agent: PHP swAsync\r\n"; $req[] = "Host:{$host}\r\n"; $req[] = "Connection:close\r\n"; $req[] = "\r\n"; $req = implode('', $req); $cli->send($req); }); $cli->on("receive", function ($cli, $data = "") use(&$httpParser, &$promise) { $ret = $httpParser->execute($data); if ($ret !== false) { Timer::del($cli->sock); $cli->isDone = true; if ($cli->isConnected()) { $cli->close(); } $promise->accept(['http_data' => $ret]); } }); $cli->on("error", function ($cli) use(&$promise) { Timer::del($cli->sock); $promise->accept(['http_data' => null, 'http_error' => 'Connect error']); }); $cli->on("close", function ($cli) use(&$promise) { }); if ($this->proxy) { $cli->connect($this->proxy['host'], $this->proxy['port'], 0.05); } else { $cli->connect($urlInfo['host'], $urlInfo['port'], 0.05); } $cli->isConnected = false; if (!$cli->errCode) { Timer::add($cli->sock, $this->timeout, function () use($cli, &$promise) { @$cli->close(); if ($cli->isConnected) { $promise->accept(['http_data' => null, 'http_error' => 'Http client read timeout']); } else { $promise->accept(['http_data' => null, 'http_error' => 'Http client connect timeout']); } }); } }
public function send(callable $callback) { $client = new \swoole_client(SWOOLE_SOCK_UDP, SWOOLE_SOCK_ASYNC); $client->on("connect", function ($cli) { $cli->send($this->data); }); $client->on('close', function ($cli) { }); $client->on('error', function ($cli) use($callback) { $cli->close(); call_user_func_array($callback, array('r' => 1, 'key' => $this->key, 'calltime' => $this->calltime, 'error_msg' => 'conncet error')); }); $client->on("receive", function ($cli, $data) use($callback) { //临时方案 Timer::del($this->key); $cli->close(); $this->calltime = microtime(true) - $this->calltime; //swoole_timer_clear($this ->timer); call_user_func_array($callback, array('r' => 0, 'key' => $this->key, 'calltime' => $this->calltime, 'data' => $data)); }); if ($client->connect($this->ip, $this->port, $this->timeout)) { $this->calltime = microtime(true); if (floatval($this->timeout) > 0) { //临时方案 Timer::add($this->key, $this->timeout, $client, $callback, array('r' => 2, 'key' => $this->key, 'calltime' => $this->calltime, 'error_msg' => 'timeout')); /* $this ->timer = swoole_timer_after(floatval($this ->timeout) * 1000, function() use($client,$callback){ $client ->close(); \SysLog::error(__METHOD__." TIMEOUT ", __CLASS__); $this ->calltime = microtime(true) - $this ->calltime; call_user_func_array($callback, array('r' => 2 ,'key' => '', 'calltime' => $this ->calltime, 'error_msg' => 'timeout')); }); */ } } }
/** * [send 异步IO,定时器设置,异常回调] * @param callable $callback [description] * @return [type] [description] */ public function send(callable $callback) { $client = new \swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC); $client->on("connect", function ($cli) { $cli->send($this->request); }); $client->on('close', function ($cli) { }); $client->on('error', function ($cli) use($callback) { $cli->close(); $this->calltime = microtime(true) - $this->calltime; call_user_func_array($callback, array('r' => 1, 'key' => $this->key, 'calltime' => $this->calltime, 'error_msg' => 'conncet error')); }); $client->on("receive", function ($cli, $data) use($callback) { /* 这里的on receivce会被触发多次,耗时和取消定时器都不在这里处理,在packRsp函数里 */ call_user_func_array(array($this, 'packRsp'), array('key' => $cli, 'data' => $data)); }); $this->callback = $callback; if ($client->connect($this->host, $this->port, $this->timeout)) { $this->calltime = microtime(true); if (floatval($this->timeout) > 0) { Timer::add($this->key, $this->timeout, $client, $callback, array('r' => 2, 'key' => $this->key, 'calltime' => $this->calltime, 'error_msg' => $this->host . ':' . $this->port . ' timeout')); } } }
public final function baz() { return function ($jobname, $job) { Timer::add(function ($event) use($jobname, $job) { // Job done $job->setResult($jobname, array('job' => 'baz', 'success' => false, 'line' => __LINE__)); $event->finish(); }, 1000.0 * 300); }; }
function setTimeout($cb, $timeout = null, $id = null, $priority = null) { return Timer::add($cb, $timeout, $id, $priority); }
/** * @todo description? * @param boolean - Hard? If hard, we shouldn't wait for graceful shutdown of the running applications. * @return boolean - Ready? */ public function shutdown($hard = FALSE) { $error = error_get_last(); if ($error) { if ($error['type'] === E_ERROR) { Daemon::log('W#' . $this->pid . ' crashed by error \'' . $error['message'] . '\' at ' . $error['file'] . ':' . $error['line']); } } if (Daemon::$config->logevents->value) { $this->log('event shutdown(' . ($hard ? 'HARD' : '') . ') invoked.'); } if (Daemon::$config->throwexceptiononshutdown->value) { throw new Exception('event shutdown'); } @ob_flush(); if ($this->terminated === TRUE) { if ($hard) { exit(0); } return; } $this->terminated = TRUE; $this->closeSockets(); $this->setStatus(3); if ($hard) { exit(0); } $this->reloadReady = $this->appInstancesReloadReady(); if ($this->reload === TRUE) { $this->reloadReady = $this->reloadReady && microtime(TRUE) > $this->reloadTime; } if (Daemon::$config->logevents->value) { $this->log('reloadReady = ' . Debug::dump($this->reloadReady)); } $n = 0; unset(Timer::$list['checkState']); Timer::add(function ($event) { $self = Daemon::$process; $self->reloadReady = $self->appInstancesReloadReady(); if ($self->reload === TRUE) { $self->reloadReady = $self->reloadReady && microtime(TRUE) > $self->reloadTime; } if (!$self->reloadReady) { $event->timeout(); } else { event_base_loopexit($self->eventBase); } }, 1000000.0, 'checkReloadReady'); while (!$this->reloadReady) { event_base_loop($this->eventBase); } //FS::waitAllEvents(); // ensure that all I/O events completed before suicide posix_kill(posix_getppid(), SIGCHLD); // praying to Master exit(0); // R.I.P. }
/** * 执行关闭流程 * @return void */ public static function stopAll() { self::$_status = self::STATUS_SHUTDOWN; // 主进程部分 if (self::$_masterPid === posix_getpid()) { self::log("Workerman[" . basename(self::$_startFile) . "] Stopping ..."); $worker_pid_array = self::getAllWorkerPids(); // 向所有子进程发送SIGINT信号,表明关闭服务 foreach ($worker_pid_array as $worker_pid) { posix_kill($worker_pid, SIGINT); Timer::add(self::KILL_WORKER_TIMER_TIME, 'posix_kill', array($worker_pid, SIGKILL), false); } } else { // 执行stop逻辑 /** @var static $worker */ foreach (self::$_workers as $worker) { $worker->stop(); } exit(0); } }