/** * Execute reload. * @return void */ protected static function reload() { // For master process. if (self::$_masterPid === posix_getpid()) { // Set reloading state. if (self::$_status !== self::STATUS_RELOADING && self::$_status !== self::STATUS_SHUTDOWN) { self::log("Workerman[" . basename(self::$_startFile) . "] reloading"); self::$_status = self::STATUS_RELOADING; } // Send reload signal to all child processes. $reloadable_pid_array = array(); foreach (self::$_pidMap as $worker_id => $worker_pid_array) { $worker = self::$_workers[$worker_id]; if ($worker->reloadable) { foreach ($worker_pid_array as $pid) { $reloadable_pid_array[$pid] = $pid; } } else { foreach ($worker_pid_array as $pid) { // Send reload signal to a worker process which reloadable is false. posix_kill($pid, SIGUSR1); } } } // Get all pids that are waiting reload. self::$_pidsToRestart = array_intersect(self::$_pidsToRestart, $reloadable_pid_array); // Reload complete. if (empty(self::$_pidsToRestart)) { if (self::$_status !== self::STATUS_SHUTDOWN) { self::$_status = self::STATUS_RUNNING; } return; } // Continue reload. $one_worker_pid = current(self::$_pidsToRestart); // Send reload signal to a worker process. posix_kill($one_worker_pid, SIGUSR1); // If the process does not exit after self::KILL_WORKER_TIMER_TIME seconds try to kill it. Timer::add(self::KILL_WORKER_TIMER_TIME, 'posix_kill', array($one_worker_pid, SIGKILL), false); } else { $worker = current(self::$_workers); // Try to emit onWorkerReload callback. if ($worker->onWorkerReload) { try { call_user_func($worker->onWorkerReload, $worker); } catch (\Exception $e) { echo $e; exit(250); } } if ($worker->reloadable) { self::stopAll(); } } }
/** * 执行平滑重启流程 * @return void */ protected static function reload() { // 主进程部分 if (self::$_masterPid === posix_getpid()) { // 设置为平滑重启状态 if (self::$_status !== self::STATUS_RELOADING && self::$_status !== self::STATUS_SHUTDOWN) { self::log("Workerman[" . basename(self::$_startFile) . "] reloading"); self::$_status = self::STATUS_RELOADING; } // 如果有worker设置了reloadable=false,则过滤掉 $reloadable_pid_array = array(); foreach (self::$_pidMap as $worker_id => $worker_pid_array) { $worker = self::$_workers[$worker_id]; if ($worker->reloadable) { foreach ($worker_pid_array as $pid) { $reloadable_pid_array[$pid] = $pid; } } } // 得到所有可以重启的进程 self::$_pidsToRestart = array_intersect(self::$_pidsToRestart, $reloadable_pid_array); // 平滑重启完毕 if (empty(self::$_pidsToRestart)) { if (self::$_status !== self::STATUS_SHUTDOWN) { self::$_status = self::STATUS_RUNNING; } return; } // 继续执行平滑重启流程 $one_worker_pid = current(self::$_pidsToRestart); // 给子进程发送平滑重启信号 posix_kill($one_worker_pid, SIGUSR1); // 定时器,如果子进程在KILL_WORKER_TIMER_TIME秒后没有退出,则强行杀死 Timer::add(self::KILL_WORKER_TIMER_TIME, 'posix_kill', array($one_worker_pid, SIGKILL), false); } else { // 如果当前worker的reloadable属性为真,则执行退出 $worker = current(self::$_workers); if ($worker->reloadable) { self::stopAll(); } } }