为什么Swoole需要在DataHead里面加上msg_id

Swoole最近的一次PR#4163中,修复了一个bug,这个bug发生的概率比较低,但是还是有发生的可能性的。

先简单描述一下bug是什么吧。

SwooleProcess模式下,master会通过管道发送数据给worker进程处理,当发送的数据(我们叫做EventData)过大的时候,就会把EventData拆分成一个一个的chunk。假设,master进程一共要发送10chunkworker进程,worker进程在接收到第5chunk之后挂了,那么还有5chunk就会积压在管道里面。此时,如果一个新的worker进程被创建,那么就会去读取管道里面残留的5chunk,但是,这剩下的5chunk是不完整的,不足以还原成原来的EventData,所以,在后续worker进程组建chunk的时候,得到的数据是不完整的,这就会导致一些内存问题。

所以,在这里,我们为每一个EventData编号了,如果发现这个EventData是上一个进程的,那么我们会丢弃这个EventData剩下的所有chunk。那么怎么判断EventData是不是上一个进程的呢?也很简单,让每个msg_id对应着一块buffer,当worker进程通过msg_id查找不到buffer的时候,就说明这个EventData进程是之前某个挂了的进程接收过的(因为同一个EventData不会被多个进程接收,所以可以通过msg_id来判断)。

代码不复杂,具体的实现可以看PR