在Swoole
最近的一次PR
#4163中,修复了一个bug
,这个bug
发生的概率比较低,但是还是有发生的可能性的。
先简单描述一下bug
是什么吧。
在Swoole
的Process
模式下,master
会通过管道发送数据给worker
进程处理,当发送的数据(我们叫做EventData
)过大的时候,就会把EventData
拆分成一个一个的chunk
。假设,master
进程一共要发送10
个chunk
给worker
进程,worker
进程在接收到第5
个chunk
之后挂了,那么还有5
个chunk
就会积压在管道里面。此时,如果一个新的worker
进程被创建,那么就会去读取管道里面残留的5
个chunk
,但是,这剩下的5
个chunk
是不完整的,不足以还原成原来的EventData
,所以,在后续worker
进程组建chunk
的时候,得到的数据是不完整的,这就会导致一些内存问题。
所以,在这里,我们为每一个EventData
编号了,如果发现这个EventData
是上一个进程的,那么我们会丢弃这个EventData
剩下的所有chunk
。那么怎么判断EventData
是不是上一个进程的呢?也很简单,让每个msg_id
对应着一块buffer
,当worker
进程通过msg_id
查找不到buffer
的时候,就说明这个EventData
进程是之前某个挂了的进程接收过的(因为同一个EventData
不会被多个进程接收,所以可以通过msg_id
来判断)。
代码不复杂,具体的实现可以看PR
。