Created
April 22, 2014 05:33
-
-
Save wangchen/11166325 to your computer and use it in GitHub Desktop.
A simple swoole timer helper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| error_reporting(E_ALL ^ E_NOTICE); | |
| /** | |
| * Timer Manager | |
| */ | |
| class TimerManager | |
| { | |
| private $_timers; | |
| private $_timeouts; | |
| public function __construct() | |
| { | |
| $this->_timers = array(); | |
| $this->_timeouts = array(); | |
| } | |
| public function addTimer($interval, $timer_key, $callback) | |
| { | |
| if (!isset($this->_timers[$interval])) { | |
| $this->_timers[$interval] = array(); | |
| } | |
| $this->_timers[$interval][$timer_key] = $callback; | |
| } | |
| public function delTimer($interval, $timer_key) | |
| { | |
| if (isset($this->_timers[$interval])) { | |
| unset($this->_timers[$interval][$timer_key]); | |
| } | |
| } | |
| public function addTimeout($interval, $timeout_key, $callback) | |
| { | |
| $t = microtime(true) + $interval / 1000; | |
| $this->_timeouts[$timeout_key] = array($t, $callback); | |
| } | |
| public function delTimeout($timeout_key) | |
| { | |
| unset($this->_timeouts[$timeout_key]); | |
| } | |
| public function dispatch($interval) | |
| { | |
| if ($interval === 1000) { | |
| echo "enter timeout branch\n"; | |
| $t = microtime(true); | |
| foreach ($this->_timeouts as $k => $to) { | |
| printf("id=%d, now=%.2f threshold=%.2f\n", $k, $t, $to[0]); | |
| if ($t > $to[0]) { | |
| echo "timeout fired\n"; | |
| if (is_callable($to[1])) { | |
| echo "invoke callback\n"; | |
| $to[1](); | |
| } | |
| unset($this->_timeouts[$k]); | |
| } | |
| } | |
| } | |
| $q = $this->_timers[$interval]; | |
| if ($q == null) { | |
| return; | |
| } | |
| printf( | |
| "timer dispatch %d, %d callbacks will be executed\n", | |
| $interval, | |
| count($q) | |
| ); | |
| while ($callback = array_shift($q)) { | |
| if (is_callable($callback)) { | |
| $callback(); | |
| } | |
| } | |
| echo "leave timer\n"; | |
| } | |
| } | |
| // It initializes in main process and shares with any other sub-processes. | |
| $TIMER_MGR = new TimerManager(); | |
| // The mini-version of Application | |
| // Just for holding the object references | |
| class Application | |
| { | |
| private static $_store; | |
| private function __construct() | |
| { | |
| /*empty*/ | |
| } | |
| private function __clone() | |
| { | |
| /*empty*/ | |
| } | |
| public static function setObject($key, $constractor) | |
| { | |
| if (!isset(self::$_store)) { | |
| self::$_store = array(); | |
| } | |
| self::$_store[$key] = array( | |
| 'constractor' => $constractor, | |
| 'instance' => null | |
| ); | |
| } | |
| public static function getObject($key) | |
| { | |
| $entry =& self::$_store[$key]; // Here must use reference | |
| $instance = $entry['instance']; | |
| if (!isset($entry['instance'])) { | |
| $instance = $entry['constractor'](); | |
| $entry['instance'] = $instance; | |
| } | |
| return $instance; | |
| } | |
| } | |
| Application::setObject( | |
| 'timer_mgr', | |
| function () use (&$TIMER_MGR) { | |
| return $TIMER_MGR; | |
| } | |
| ); | |
| $serv = new swoole_server("0.0.0.0", 9501); | |
| $serv->set(array( | |
| 'reactor_num' => 2, | |
| 'writer_num' => 2, | |
| 'worker_num' => 2, | |
| 'task_worker_num' => 2, | |
| 'dispatch_mode' => 2, | |
| 'max_conn' => 100000, | |
| 'max_request' => 5000, | |
| 'backlog' => 1000, | |
| 'open_cpu_affinity' => 1, | |
| 'open_tcp_nodelay' => 1, | |
| 'log_file' => '/alidata1/logs/app/swoole.log', | |
| 'daemonize' => 0, | |
| )); | |
| $serv->on( | |
| 'Start', | |
| function ($serv) { | |
| printf("server started, pid=%d\n", posix_getpid()); | |
| } | |
| ); | |
| $serv->on( | |
| 'Receive', | |
| function (swoole_server $serv, $fd, $from_id, $data) { | |
| echo "enter receive\n"; | |
| $data = trim($data); | |
| $timer_mgr = Application::getObject("timer_mgr"); | |
| $uid = 1; | |
| $timeout_key = "rest_auto::$uid"; // a business related key, eg. UID | |
| $timer_mgr->addTimeout(5000, $timeout_key, function () use ($uid) { | |
| // Should use swoole task to do the jobs | |
| // Avoid using sync operations | |
| echo "reset palyer '$uid' auto\n"; | |
| }); | |
| $serv->addtimer(1000); | |
| echo "leave receive\n"; | |
| } | |
| ); | |
| $serv->on( | |
| 'Task', | |
| function (swoole_server $serv, $task_id, $from_id, $data) { | |
| $task = Application::getObject('task'); | |
| $task->dispatch($serv, $task_id, $from_id, $data); | |
| } | |
| ); | |
| $serv->on( | |
| 'Finish', | |
| function () { | |
| echo "task finished\n"; | |
| } | |
| ); | |
| $serv->on('WorkerStart', function ($serv, $worker_id) { | |
| global $argv; | |
| if ($worker_id >= $serv->setting['worker_num']) { | |
| swoole_set_process_name("php {$argv[0]} task worker"); | |
| printf("task worker started, pid=%d\n", posix_getpid()); | |
| } else { | |
| swoole_set_process_name("php {$argv[0]} event worker"); | |
| printf("worker started, pid=%d\n", posix_getpid()); | |
| } | |
| }); | |
| $serv->on('Timer', function ($serv, $interval) { | |
| echo "enter timer\n"; | |
| Application::getObject("timer_mgr")->dispatch($interval); | |
| echo "leave timer\n"; | |
| }); | |
| $serv->start(); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Send anything to server, a job scheduled and will be executed after 2 secs.
echo 1 |nc 127.0.0.1 9501