ソースを参照

some optimization

walkor 8 年 前
コミット
16bcc9edbf
2 ファイル変更41 行追加284 行削除
  1. 0 265
      Events/React.php
  2. 41 19
      Worker.php

+ 0 - 265
Events/React.php

@@ -1,265 +0,0 @@
-<?php
-/**
- * This file is part of workerman.
- *
- * Licensed under The MIT License
- * For full copyright and license information, please see the MIT-LICENSE.txt
- * Redistributions of files must retain the above copyright notice.
- *
- * @author    walkor<walkor@workerman.net>
- * @copyright walkor<walkor@workerman.net>
- * @link      http://www.workerman.net/
- * @license   http://www.opensource.org/licenses/mit-license.php MIT License
- */
-namespace Workerman\Events;
-use React\EventLoop\LoopInterface;
-use React\EventLoop\Timer\TimerInterface;
-
-/**
- * select eventloop
- */
-class React implements LoopInterface
-{
-    /**
-     * @var React\EventLoop\LoopInterface
-     */
-    protected $_loop = null;
-
-    /**
-     * @var array
-     */
-    protected $_timerIdMap = array();
-
-    /**
-     * @var int
-     */
-    protected $_timerIdIndex = 0;
-
-    /**
-     * React constructor.
-     */
-    public function __construct() {
-        if (function_exists('event_base_new')) {
-            $this->_loop = new \Workerman\Events\React\LibEventLoop();
-        } elseif (class_exists('EventBase', false)) {
-            $this->_loop = new \Workerman\Events\React\ExtEventLoop();
-        } else {
-            $this->_loop = new \Workerman\Events\React\StreamSelectLoop();
-        }
-    }
-
-    /**
-     * Add event listener to event loop.
-     *
-     * @param $fd
-     * @param $flag
-     * @param $func
-     * @param array $args
-     * @return bool
-     */
-    public function add($fd, $flag, $func, $args = array())
-    {
-        $args = (array)$args;
-        switch ($flag) {
-            case EventInterface::EV_READ:
-                return $this->_loop->addReadStream($fd, $func);
-            case EventInterface::EV_WRITE:
-                return $this->_loop->addWriteStream($fd, $func);
-            case EventInterface::EV_SIGNAL:
-                return $this->_loop->addSignal($fd, $func);
-            case EventInterface::EV_TIMER:
-                $timer_obj = $this->_loop->addPeriodicTimer($fd, function() use ($func, $args) {
-                    call_user_func_array($func, $args);
-                });
-                $this->_timerIdMap[++$this->_timerIdIndex] = $timer_obj;
-                return $this->_timerIdIndex;
-            case EventInterface::EV_TIMER_ONCE:
-                $timer_obj = $this->_loop->addTimer($fd, function() use ($func, $args) {
-                    call_user_func_array($func, $args);
-                });
-                $this->_timerIdMap[++$this->_timerIdIndex] = $timer_obj;
-                return $this->_timerIdIndex;
-        }
-        return false;
-    }
-
-    /**
-     * Remove event listener from event loop.
-     *
-     * @param mixed $fd
-     * @param int   $flag
-     * @return bool
-     */
-    public function del($fd, $flag)
-    {
-        switch ($flag) {
-            case EventInterface::EV_READ:
-                return $this->_loop->removeReadStream($fd);
-            case EventInterface::EV_WRITE:
-                return $this->_loop->removeWriteStream($fd);
-            case EventInterface::EV_SIGNAL:
-                return $this->_loop->removeSignal($fd);
-            case EventInterface::EV_TIMER:
-            case EventInterface::EV_TIMER_ONCE;
-                if (isset($this->_timerIdMap[$fd])){
-                    $timer_obj = $this->_timerIdMap[$fd];
-                    unset($this->_timerIdMap[$fd]);
-                    $this->_loop->cancelTimer($timer_obj);
-                    return true;
-                }
-        }
-        return false;
-    }
-
-
-    /**
-     * Main loop.
-     *
-     * @return void
-     */
-    public function loop()
-    {
-        $this->_loop->run();
-    }
-
-    /**
-     * Register a listener to be notified when a stream is ready to read.
-     *
-     * @param resource $stream   The PHP stream resource to check.
-     * @param callable $listener Invoked when the stream is ready.
-     */
-    public function addReadStream($stream, callable $listener) {
-        return call_user_func(array($this->_loop, 'addReadStream'), $stream, $listener);
-    }
-
-    /**
-     * Register a listener to be notified when a stream is ready to write.
-     *
-     * @param resource $stream   The PHP stream resource to check.
-     * @param callable $listener Invoked when the stream is ready.
-     */
-    public function addWriteStream($stream, callable $listener) {
-        return call_user_func(array($this->_loop, 'addWriteStream'), $stream, $listener);
-    }
-
-    /**
-     * Remove the read event listener for the given stream.
-     *
-     * @param resource $stream The PHP stream resource.
-     */
-    public function removeReadStream($stream) {
-        return call_user_func(array($this->_loop, 'removeReadStream'), $stream);
-    }
-
-    /**
-     * Remove the write event listener for the given stream.
-     *
-     * @param resource $stream The PHP stream resource.
-     */
-    public function removeWriteStream($stream) {
-        return call_user_func(array($this->_loop, 'removeWriteStream'), $stream);
-    }
-
-    /**
-     * Remove all listeners for the given stream.
-     *
-     * @param resource $stream The PHP stream resource.
-     */
-    public function removeStream($stream) {
-        return call_user_func(array($this->_loop, 'removeStream'), $stream);
-    }
-
-    /**
-     * Enqueue a callback to be invoked once after the given interval.
-     *
-     * The execution order of timers scheduled to execute at the same time is
-     * not guaranteed.
-     *
-     * @param int|float $interval The number of seconds to wait before execution.
-     * @param callable  $callback The callback to invoke.
-     *
-     * @return TimerInterface
-     */
-    public function addTimer($interval, callable $callback) {
-        return call_user_func(array($this->_loop, 'addTimer'), $interval, $callback);
-    }
-
-    /**
-     * Enqueue a callback to be invoked repeatedly after the given interval.
-     *
-     * The execution order of timers scheduled to execute at the same time is
-     * not guaranteed.
-     *
-     * @param int|float $interval The number of seconds to wait before execution.
-     * @param callable  $callback The callback to invoke.
-     *
-     * @return TimerInterface
-     */
-    public function addPeriodicTimer($interval, callable $callback) {
-        return call_user_func(array($this->_loop, 'addPeriodicTimer'), $interval, $callback);
-    }
-
-    /**
-     * Cancel a pending timer.
-     *
-     * @param TimerInterface $timer The timer to cancel.
-     */
-    public function cancelTimer(TimerInterface $timer) {
-        return call_user_func(array($this->_loop, 'cancelTimer'), $timer);
-    }
-
-    /**
-     * Check if a given timer is active.
-     *
-     * @param TimerInterface $timer The timer to check.
-     *
-     * @return boolean True if the timer is still enqueued for execution.
-     */
-    public function isTimerActive(TimerInterface $timer) {
-        return call_user_func(array($this->_loop, 'isTimerActive'), $timer);
-    }
-
-    /**
-     * Schedule a callback to be invoked on the next tick of the event loop.
-     *
-     * Callbacks are guaranteed to be executed in the order they are enqueued,
-     * before any timer or stream events.
-     *
-     * @param callable $listener The callback to invoke.
-     */
-    public function nextTick(callable $listener) {
-        return call_user_func(array($this->_loop, 'nextTick'), $listener);
-    }
-
-    /**
-     * Schedule a callback to be invoked on a future tick of the event loop.
-     *
-     * Callbacks are guaranteed to be executed in the order they are enqueued.
-     *
-     * @param callable $listener The callback to invoke.
-     */
-    public function futureTick(callable $listener) {
-        return call_user_func(array($this->_loop, 'futureTick'), $listener);
-    }
-
-    /**
-     * Perform a single iteration of the event loop.
-     */
-    public function tick() {
-        return call_user_func(array($this->_loop, 'tick'));
-    }
-
-    /**
-     * Run the event loop until there are no more tasks to perform.
-     */
-    public function run() {
-        return call_user_func(array($this->_loop, 'run'));
-    }
-
-    /**
-     * Instruct a running event loop to stop.
-     */
-    public function stop() {
-        return call_user_func(array($this->_loop, 'stop'));
-    }
-}

+ 41 - 19
Worker.php

@@ -33,7 +33,7 @@ class Worker
      *
      * @var string
      */
-    const VERSION = '3.3.9';
+    const VERSION = '3.4.0';
 
     /**
      * Status starting.
@@ -274,6 +274,13 @@ class Worker
     public static $onMasterStop = null;
 
     /**
+     * EventLoopClass
+     *
+     * @var string
+     */
+    public static $eventLoopClass = '';
+
+    /**
      * The PID of master process.
      *
      * @var int
@@ -390,19 +397,11 @@ class Worker
      * @var array
      */
     protected static $_availableEventLoops = array(
-        'libevent',
-        'event',
-        'ev'
+        'libevent' => '\Workerman\Events\Libevent',
+        'event'    => '\Workerman\Events\Event'
     );
 
     /**
-     * Current eventLoop name.
-     *
-     * @var string
-     */
-    protected static $_eventLoopName = 'select';
-
-    /**
      * PHP built-in protocols.
      *
      * @var array
@@ -850,16 +849,38 @@ class Worker
      */
     protected static function getEventLoopName()
     {
-        if (interface_exists('\React\EventLoop\LoopInterface')) {
-            return 'React';
+        if (self::$eventLoopClass) {
+            return self::$eventLoopClass;
         }
-        foreach (self::$_availableEventLoops as $name) {
+
+        $loop_name = '';
+        foreach (self::$_availableEventLoops as $name=>$class) {
             if (extension_loaded($name)) {
-                self::$_eventLoopName = $name;
+                $loop_name = $name;
                 break;
             }
         }
-        return self::$_eventLoopName;
+
+        if ($loop_name) {
+            if (interface_exists('\React\EventLoop\LoopInterface')) {
+                switch ($loop_name) {
+                    case 'libevent':
+                        self::$eventLoopClass = '\Workerman\Events\React\LibEventLoop';
+                        break;
+                    case 'event':
+                        self::$eventLoopClass = '\Workerman\Events\React\ExtEventLoop';
+                        break;
+                    default :
+                        self::$eventLoopClass = '\Workerman\Events\React\StreamSelectLoop';
+                        break;
+                }
+            } else {
+                self::$eventLoopClass = self::$_availableEventLoops[$loop_name];
+            }
+        } else {
+            self::$eventLoopClass = '\Workerman\Events\Select';
+        }
+        return self::$eventLoopClass;
     }
 
     /**
@@ -1199,6 +1220,7 @@ class Worker
             foreach (self::$_workers as $worker) {
                 $worker->stop();
             }
+            self::$globalEvent->destroy();
             exit(0);
         }
     }
@@ -1212,7 +1234,7 @@ class Worker
     {
         // For master process.
         if (self::$_masterPid === posix_getpid()) {
-            $loadavg = function_exists('sys_getloadavg') ? sys_getloadavg() : array('-', '-', '-');
+            $loadavg = function_exists('sys_getloadavg') ? array_map('round', sys_getloadavg(), array(2)) : array('-', '-', '-');
             file_put_contents(self::$_statisticsFile,
                 "---------------------------------------GLOBAL STATUS--------------------------------------------\n");
             file_put_contents(self::$_statisticsFile,
@@ -1502,8 +1524,8 @@ class Worker
 
         // Create a global event loop.
         if (!self::$globalEvent) {
-            $eventLoopClass    = "\\Workerman\\Events\\" . ucfirst(self::getEventLoopName());
-            self::$globalEvent = new $eventLoopClass;
+            $event_loop_class = self::getEventLoopName();
+            self::$globalEvent = new $event_loop_class;
             // Register a listener to be notified when server socket is ready to read.
             if ($this->_socketName) {
                 if ($this->transport !== 'udp') {