swoole / phpkafka

PHP Kafka client is used in PHP-FPM and Swoole. PHP Kafka client supports 50 APIs, which might be one that supports the most message types ever.
https://longlang.org/
Apache License 2.0
270 stars 47 forks source link

设置了exception callback 可能会死循环 #64

Open chunhei2008 opened 2 years ago

chunhei2008 commented 2 years ago

// SwooleClient.php

   private function startRecvCo(): void
    {
        $this->coRecvRunning = true;
        $this->recvCoId = true;
        $this->recvCoId = Coroutine::create(function () {
            while ($this->coRecvRunning) {
                try {
                    $data = $this->socket->recv(4, -1);
                    if ($data === '') {
                        break;
                    }
                    $length = Int32::unpack($data);
                    $data = $this->socket->recv($length);
                    $correlationId = Int32::unpack($data);
                    if (isset($this->recvChannels[$correlationId])) {
                        $this->recvChannels[$correlationId]->push($data);
                    }
                } catch (Exception $e) {
                    if ($e instanceof SocketException && ! $this->connected) {
                        return;
                    }
                    $callback = $this->getConfig()->getExceptionCallback();
                    if ($callback) {
                        //  已经设置了 exception callback 没有退出就会一直死循环下去
                        $callback($e);
                        // 修复方案:在此次增加 return 
                        return;
                    } else {
                        throw $e;
                    }
                }
            }
        });
    }
shuifa commented 2 years ago
  • 问题代码&修复方案

// SwooleClient.php

   private function startRecvCo(): void
    {
        $this->coRecvRunning = true;
        $this->recvCoId = true;
        $this->recvCoId = Coroutine::create(function () {
            while ($this->coRecvRunning) {
                try {
                    $data = $this->socket->recv(4, -1);
                    if ($data === '') {
                        break;
                    }
                    $length = Int32::unpack($data);
                    $data = $this->socket->recv($length);
                    $correlationId = Int32::unpack($data);
                    if (isset($this->recvChannels[$correlationId])) {
                        $this->recvChannels[$correlationId]->push($data);
                    }
                } catch (Exception $e) {
                    if ($e instanceof SocketException && ! $this->connected) {
                        return;
                    }
                    $callback = $this->getConfig()->getExceptionCallback();
                    if ($callback) {
                        //  已经设置了 exception callback 没有退出就会一直死循环下去
                        $callback($e);
                        // 修复方案:在此次增加 return 
                        return;
                    } else {
                        throw $e;
                    }
                }
            }
        });
    }

你这没有解决吧。如果callback死循环了。还是走不到return啊

shuifa commented 2 years ago
  • 问题代码&修复方案

// SwooleClient.php

   private function startRecvCo(): void
    {
        $this->coRecvRunning = true;
        $this->recvCoId = true;
        $this->recvCoId = Coroutine::create(function () {
            while ($this->coRecvRunning) {
                try {
                    $data = $this->socket->recv(4, -1);
                    if ($data === '') {
                        break;
                    }
                    $length = Int32::unpack($data);
                    $data = $this->socket->recv($length);
                    $correlationId = Int32::unpack($data);
                    if (isset($this->recvChannels[$correlationId])) {
                        $this->recvChannels[$correlationId]->push($data);
                    }
                } catch (Exception $e) {
                    if ($e instanceof SocketException && ! $this->connected) {
                        return;
                    }
                    $callback = $this->getConfig()->getExceptionCallback();
                    if ($callback) {
                        //  已经设置了 exception callback 没有退出就会一直死循环下去
                        $callback($e);
                        // 修复方案:在此次增加 return 
                        return;
                    } else {
                        throw $e;
                    }
                }
            }
        });
    }

我到是觉得这里的 创建协程用的是 Swoole\Coroutine ,如果没有设置callback 就会抛出异常。。这样会导致php的致命错误。当前进程会被kiil。这里是不合理的。。。