毫秒级定时器

Libevent支持文件描述符、信号、定时器三种事件对象,beyod对其进行了封装,使之有一致的调用接口。

beyod使用libevent实际毫秒级定时器,一般来说,常用的定时器有两种:一次性定时器、重复定时器,beyod支持这两种定时器:

一次性定时器:

$timerid = \Yii::$app->eventLooper->addTimemout($interval, $callback, $arg);

重复定时器:

$timerid = \Yii::$app->eventLooper->addInterval($interval, $callback, $arg);

$interval
定时器的间隔,单位为毫秒。
$callback 要执行的回调函数, 参数签名为:

/**
* @param int $timerid 创建的定时器id
* @param int $interval 定义定时器时的毫秒间隔
* @param int $flag  \beyoio\event\EventLooper::EV_TIMEOUT | \beyoio\event\EventLooper::EV_INTERVAL 定时器类型
* @param mixed $arg 创建定时器时的传递的额外参数
*/
function($timerid, $interval, $flag, $arg){
    
}

定时器的取消

\Yii::$app->eventLooper->delTimeout($timerid); //取消已经定义的一次性定时器
\Yii::$app->eventLooper->delInterval($timerid); //取消重复定时器

一次性定时器在激活运行后,相关的资源自动被删除,无须调用者手工清理。

重复定时器会周期性执行,一旦运行后,必须由调用者负责资源清理,否则可能造成内存泄露。

如Listener的空闲连接自动清理逻辑, 就使用了定时器:

public function keepaliveProbe() {
        if($this->keepalive_interval <=0 || $this->keepalive_timeout <=0){
            return ;
        }
        
        $this->keepalive_timer = Yii::$app->eventLooper->addInterval($this->keepalive_interval*1000, function($timerId, $interval, $flag, $args=null){
            $now = microtime(true);
            Yii::debug("keepalive probing ...", 'beyoio');
            foreach($this->connections as $id =>$conn){
                if($conn->request_at >0 && $conn->request_at < ($now - $this->keepalive_timeout)){
                    Yii::debug($conn." keepalive timed out,close it",'beyoio');
                    $conn->close();
                }
            }
        });
    }