pitaya icon indicating copy to clipboard operation
pitaya copied to clipboard

Concerns about the Global Message Channel 'chLocalProcess' in Pitaya

Open f2ngwx opened this issue 1 year ago • 6 comments

In the Pitaya framework, all player messages are ultimately routed to a global channel called 'chLocalProcess.' I'm not quite clear on the reasoning behind this design choice. As it stands, I believe this design could potentially lead to performance issues and impact the overall gameplay experience for players. For instance, if one player experiences latency or freezes, it could affect other players' game processes. In extreme cases, if the default dispatch coroutine is occupied by a single player, causing significant delays, it would essentially render the game unplayable for others.

Would it be possible to shed some light on the rationale behind this design decision? Wouldn't it be more effective to have each player handle their own messages within their respective coroutines for a better gaming experience?

f2ngwx avatar Jul 20 '23 08:07 f2ngwx

The channel is buffered with a configurable buffer size. For one player to block others, it would have to send a number of messages equal to the buffer. I believe the concern is valid but it's also a corner case that we didn't hit yet

felipejfc avatar Sep 06 '23 17:09 felipejfc

"We've encountered this issue before, where online players couldn't send messages in a timely manner due to some reasons. As a result, messages accumulated in the 'chSend' channel, causing one of the goroutines in 'Dispatch' to block, and eventually, all 'Dispatch' goroutines got blocked, leading to the server shutting down. In Pitaya, each agent has its independent channel. Is it possible to process players' messages in these individual channels? This approach has two benefits:

  1. It ensures that players' own messages are ordered.
  2. If there are issues as mentioned above, it won't affect other players' game progress.

I've mainly made the following changes:

  1. In the 'processMessage' function of 'HandlerService,' replace the line 'h.chLocalProcess <- message' with 'h.localProcess(lm.ctx, lm.agent, lm.route, lm.msg).'
  2. Replace the line 'h.chRemoteProcess <- message' with 'h.remoteService.remoteProcess(rm.ctx, nil, rm.agent, rm.route, rm.msg).' In summary, we've removed the 'chRemoteProcess' and 'chLocalProcess' channels."

f2ngwx avatar Sep 07 '23 02:09 f2ngwx

I think what you did isn't going to solve the root cause of the issue. If the local/remote processing takes too long, what will happen is that your stack will blow up because of these calls. You could have achieved the same result by just increasing the size of these channels. I think the proper "fix" here would be to create shards using playerids and sending them to different channels

felipejfc avatar Sep 13 '23 14:09 felipejfc

I think it is very dangerous to process the same player's data in parallel, and there must be a mechanism to make the messages on the route execute sequentially, otherwise a lot of data will have to be locked

lyh1091106900 avatar Sep 25 '23 04:09 lyh1091106900

The player's gourutinue should know the signal of the end of the previous message processing and then process the next message

lyh1091106900 avatar Sep 25 '23 04:09 lyh1091106900

process players' messages in these individual channels?

I think the issue is exist, but I don't think the change you said could solve it completely. Thinking about the scene of two different session from a same UID, while the old one is blocked, the new one will run on a different goroutine that would cause the issue.

So, for me, now I use some mutex logic to prevent it, though I think it is not graceful enough, hopefully pitaya could provide a perfect solution to do it, maybe something like "actor"?

bruce1125 avatar Dec 11 '23 01:12 bruce1125