Swoole 协程暂停、恢复下载任务原理

"本文介绍了Swoole协程工作进程的状态管理,包括启动、运行、退出、暂停和恢复。在接收到信号时,工作进程会相应地改变其状态。在暂停状态下,工作进程会停止运行,而在恢复状态下则会继续执行。同时,文章展示了如何通过`SwooleCoroutineWaitGroup`来控制协程的运行与暂停。"
摘要由CSDN通过智能技术生成
run(function () {
    class Worker
    {
        // 正在启动
        const STATE_CURRENT_STARTING = 1;

        // 正在运行
        const STATE_CURRENT_RUNNING = 2;

        // 退出状态
        const STATE_CURRENT_QUIT = 3;

        // 暂停完成
        const STATE_CURRENT_SUSPENDED = 4;

        /**
         * 暂停中
         */
        const STATE_CURRENT_PAUSED = 5;

        /**
         * 运行状态
         * @var int $stateCurrent
         */
        protected static int $stateCurrent = self::STATE_CURRENT_STARTING;

        /**
         * @var array $listCoroutine
         */
        protected static array $listCoroutine = [
//        '1' => '运行状态',
//        '2' => '运行状态'
        ];

        protected \Swoole\Coroutine\WaitGroup $wg;

        public function __construct()
        {
            $this->wg = new \Swoole\Coroutine\WaitGroup();
            \Swoole\Process::signal(SIGTERM, [$this, 'workerQuit']);
            \Swoole\Process::signal(SIGINT, [$this, 'workerPauseResume']);
        }

        public function workerQuit()
        {
            if (static::$stateCurrent == static::STATE_CURRENT_RUNNING) {
                static::$stateCurrent = static::STATE_CURRENT_QUIT;
            }
        }

        public function workerPauseResume()
        {
            if (static::$stateCurrent == static::STATE_CURRENT_RUNNING) {
                static::$stateCurrent = static::STATE_CURRENT_PAUSED;
                if (static::STATE_CURRENT_PAUSED === static::$stateCurrent) {   // 暂停
                    var_dump('暂停运行中');
                }
            } elseif (static::STATE_CURRENT_PAUSED === static::$stateCurrent) { // 恢复
                var_dump('恢复运行中');
                var_dump(static::$listCoroutine);
                static::$stateCurrent = static::STATE_CURRENT_SUSPENDED;
                self::suspended();
                var_dump('恢复运行成功');
            }
        }

        public function run()
        {
            $this->pool(4);
//            $this->running();
            $this->wg->wait();
        }

        protected function running()
        {
            $timerId = \Swoole\Timer::tick(500, function () use (&$timerId) {
                if (static::$stateCurrent == static::STATE_CURRENT_QUIT) {
                    var_dump('Stop all success!');
                    Swoole\Timer::clear($timerId);
                }
            });
        }

        private static function suspended(): bool
        {
            $success = true;
            // 恢复状态
            if (static::$stateCurrent === self::STATE_CURRENT_SUSPENDED) {
                foreach (static::$listCoroutine as $coroutineId => $current_state) {
                    if ($current_state === self::STATE_CURRENT_PAUSED) {
                        // 恢复运行状态
                        static::$listCoroutine[$coroutineId] = static::STATE_CURRENT_RUNNING;
                        \Swoole\Coroutine::resume($coroutineId);
                    } else {
                        $success = false;
                        break;
                    }
                }
            }
            if ($success) {
                static::$stateCurrent = static::STATE_CURRENT_RUNNING;
            }
            return $success;
        }

        // 暂停运行
        private static function stopCurrent()
        {
            if (static::$stateCurrent === self::STATE_CURRENT_PAUSED) {
                $cid = \Swoole\Coroutine::getCid();
                static::$listCoroutine[$cid] = static::STATE_CURRENT_PAUSED;
                var_dump('coroutine_id: [' . $cid . '] 暂停运行成功');

                $count = 0;
                foreach (static::$listCoroutine as $coroutineId => $current_state) {
                    if ($current_state === self::STATE_CURRENT_PAUSED) {
                        ++$count;
                        if ($count == count(static::$listCoroutine)) {
                            var_dump('全部已暂停运行');
                        }
                    }
                }

                \Swoole\Coroutine::suspend();
            }
        }

        protected function pool(int $worker_num = 4): array
        {
            for ($i = 1; $i <= $worker_num; $i++) {
                $this->wg->add();
                $coroutineId = \Swoole\Coroutine::create(function () {
                    \Swoole\Coroutine::defer(fn () => $this->wg->done());
                    while (1) {
                        if (static::$stateCurrent === self::STATE_CURRENT_QUIT) {
                            var_dump('Quit worker.');
                            return;
                        }

                        self::stopCurrent();

                        var_dump('data ....');
                        var_dump('writing ....');
                        \Swoole\Coroutine::sleep(0.5);
                        var_dump('write success ....');
                    }
                });

                static::$listCoroutine[$coroutineId] = static::STATE_CURRENT_RUNNING;
            }
            static::$stateCurrent = static::STATE_CURRENT_RUNNING;
            return static::$listCoroutine;
        }

    }

//    $worker = new Worker();
//    $worker->run();
});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值