资源的有效释放始终是个艰难的问题。特别是在具体的业务逻辑中,由于逻辑的多变和复杂,导致出错的可能性大大增加。
举个例子,游戏服务器,一个房间中等到所有人都不在的时候就销毁房间。而当房主退出的时候,要踢出所有人。假设所有人退出都走同样的 exit 逻辑,并且 exit 逻辑里面判断人数为 0 就销毁房间。这样就很糟了,exit 调用 exit,中间有个环节出错,房间就不释放了。
怎么做才是安全的呢?标记状态+超时处理。当房主退出的时候,直接就标记房间状态为 releasing,并加上超时时间,由另外的 tick 逻辑去保证最终会销毁这个房间。
总结起来,最核心就 3 条(够应付大多数“资源创建/状态变化/回收”系统):
1、先定目标,再走流程
把“最终要达到的事实”先写成状态/标记(例如“必须释放/必须踢出/必须回滚”),流程只是实现手段;流程失败也不能让目标失效。
2、回收做成独立闭环:标记→清扫(可重试+有超时)
不要把释放绑在某条复杂流程的末尾;一旦该释放就先标记进入回收态,然后由独立清扫逻辑反复尝试,超时强制收敛到终态。
3、共享状态只允许一个写入口(串行化)
所有改变同一份状态的操作必须走同一个队列/actor/事务,保证幂等与可重入;外部调用(RPC/IO)放在状态机外,失败只影响“是否优雅”,不影响最终收敛。