swoole / grpc

💎 Grpc client based on Swoole Coroutine
Apache License 2.0
199 stars 21 forks source link

并发量大的时候经常发生错误 #18

Open bnubobby opened 4 years ago

bnubobby commented 4 years ago

显示: Fatal error: Uncaught Swoole\Error: Socket#33 has already been bound to another coroutine#852, writing of the same socket in coroutine#853 at the same time is not allowed in

twose commented 4 years ago

创建客户端的时候opts参数传入['send_yield => true']即可解决

bnubobby commented 4 years ago

已传入 ['send_yield => true'] 问题依旧

bnubobby commented 4 years ago

尝试复用同一个 stream ,然后使用write() 写入数据,问题解决

islenbo commented 3 years ago

@twose 1、我最近也遇到这个问题,看了\Grpc\Client的源码后发现,在start()方法中开了两个协程,一个recv,一个send,当程序执行“过快”时,就会发生 @bnubobby 所提到的错误,在两个协程中加一个sleep,让代码先执行到 Grpc/Client.php 第143行前后的 $this->client->recv(-1);,再触发send协程中的$this->client->send(),就不会报错了。

2、看了Http2客户端的文档,似乎还没支持send_yield,所以加了这个配置不生效。 https://wiki.swoole.com/#/client?id=%e9%85%8d%e7%bd%ae

twose commented 3 years ago

send_yield是grpc客户端源码里自己实现的,不是Swoole提供的。 贴一下你的报错?

islenbo commented 3 years ago
PHP Fatal error:  Uncaught Swoole\Error: Socket#7 has already been bound to another coroutine#3, writing of the same socket in coroutine#2 at the same time is not allowed in /var/www/html/vendor/swoole/grpc/src/Grpc/Client.php:145
Stack trace:
#0 /var/www/html/vendor/swoole/grpc/src/Grpc/Client.php(145): Swoole\Coroutine\Http2\Client->recv(-1)
#1 {main}
  thrown in /var/www/html/vendor/swoole/grpc/src/Grpc/Client.php

我在swoole/grpc这个包里没看到send_yield相关的代码,swoole/grpc的版本是1.0.3。

twose commented 3 years ago

不对啊,你Swoole啥版本的,Swoole很早以前就支持同时读写,一读一写了

islenbo commented 3 years ago
swoole

Swoole => enabled
Author => Swoole Team <team@swoole.com>
Version => 4.6.6
Built => Aug  4 2021 02:27:24
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
openssl => OpenSSL 1.1.0l  10 Sep 2019
dtls => enabled
http2 => enabled
zlib => 1.2.8
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled
async_redis => enabled

Directive => Local Value => Master Value
swoole.enable_coroutine => On => On
swoole.enable_library => On => On
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.unixsock_buffer_size => 8388608 => 8388608

4.6.6,这个版本应该是支持的一读一写的。然后我刚刚试了一下,把写协程放到读协程前面,这个报错是必现的。

twose commented 3 years ago

这里底层实现有问题,因为recv的时候可能会触发帧更新,导致和写操作冲突了,我稍晚看看怎么解决一下

longxinH commented 2 years ago

@twose 目前读写冲突的问题解决了吗?尝试了4.8.3问题还在