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);
     }
 }
Esempio n. 3
0
 /**
  * @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']);
             }
         });
     }
 }
Esempio n. 5
0
File: UDP.php Progetto: RamboLau/tsf
 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'));
                     });
             */
         }
     }
 }
Esempio n. 6
0
File: HTTP.php Progetto: jsRuner/tsf
 /**
  * [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'));
         }
     }
 }
Esempio n. 7
0
 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);
     };
 }
Esempio n. 8
0
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.
 }
Esempio n. 10
0
 /**
  * 执行关闭流程
  * @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);
     }
 }