Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle message session wrap around #1797

Closed
wants to merge 1 commit into from
Closed

Conversation

t0350
Copy link
Contributor

@t0350 t0350 commented Sep 27, 2023

session 目前只有 int32_t。如果项目中使用 skynet.call,并且对端服务通过 skynet.response hold 住返回值,那 session 回绕后这部分 skynet.call 可能被错误唤醒了。(应该不会错误唤醒, 但是 session 上下文被覆盖了,后续报 unknown session)

sizeof(struct skyent_message) 会由 24 字节变为 32 字节。不过看了下 jemalloc 16~32 字节间没有其他 sizeclass,应该最终内存也没有啥变化。

@sniper00
Copy link
Contributor

如果你平均一秒1w次call 要持续 59小时才会回绕, 没有什么游戏业务能忍受 59小时的延迟吧。 就算你瞬间达到 21亿次call,一个lua协程大概占用1KB内存, 大概需要2T的内存,估计是先OOM.

@t0350
Copy link
Contributor Author

t0350 commented Sep 27, 2023

如果你平均一秒1w次call 要持续 59小时才会回绕, 没有什么游戏业务能忍受 59小时的延迟吧。 就算你瞬间达到 21亿次call,一个lua协程大概占用1KB内存, 大概需要2T的内存,估计是先OOM.

是特定用法。比如 sharedata.query 的 monitor 协程。更新的时候才返回。https://github.com/cloudwu/skynet/blob/master/lualib/skynet/sharedata.lua#L16 @sniper00

@cloudwu
Copy link
Owner

cloudwu commented Sep 27, 2023

我要想想有没有别的解决方案,我倾向于不改大到 64bits 。

@t0350
Copy link
Contributor Author

t0350 commented Sep 27, 2023

想了还有个方案是把 new_session 给到 lua 层,重复 session 情况是少数,这样来处理取一个有效的 session 。

@cloudwu
Copy link
Owner

cloudwu commented Sep 27, 2023

因为只有两个地方会自动分配 id ,一个是 send 传 nil ,一个是 timeout 。

我觉得可以简单实现的方法是:每次分配完 id 回到 lua 层后,把返回的 session + 1 看看后一个会不会和过去的冲突,如果冲突,就故意再分配一个跳过去。

而且,上面的操作可以通过封装 send 函数完成。在 session 还没有回绕时,不启用检查。发现回绕或后,再通过 lua 函数替换掉有检查的版本。

@t0350
Copy link
Contributor Author

t0350 commented Sep 27, 2023

没有回绕时不启用检查,回绕后再替换,这个没有太理解。先按上面那样改了一版。

@t0350 t0350 changed the title promote session to int64 handle message session wrap around Sep 27, 2023
@cloudwu
Copy link
Owner

cloudwu commented Sep 27, 2023

因为大部份服务不会活到 session 回绕,所以检查是没有意义的。只需要发现回绕后,替换成这个带检查版本的 send 就可以了。

@t0350
Copy link
Contributor Author

t0350 commented Sep 28, 2023

= = 还是想不明白怎么做到。
我理解处理不回绕的 case 越简单越好,但是要检查回绕的话应该怎么也避免不了要做 session 判断,这个不另外写到现在实现的 auxsend 里,就需要每个 c.send 的逻辑判断才能做到吧?想不到其他的做法。

@cloudwu cloudwu mentioned this pull request Sep 28, 2023
@cloudwu
Copy link
Owner

cloudwu commented Sep 28, 2023

#1798 @t0350 看看我的实现,帮忙测试一下。(我没有测试)

思路是,设置一个危险区,不在危险区时,检查代码最少(一般经过一个数字比较判断就可以跳过)。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants