我想知道当它们与密钥相关联时如何处理临时 gen_servers 状态的保存。
要将键与进程关联,我使用了一个名为 pidstore 的进程。Pidstore 最终启动进程。我给 pidstore 一个 Key 和一个 M,F,A,它在全局中查找密钥,然后如果找到则返回 pid 或应用 MFA(必须返回 {ok, Pid}),用密钥注册 Pid全局并返回 Pid。
我可能有许多不活动的 gen_servers,它们的状态可能很大。因此,我设置了 handle_info 回调以将状态保存在我的数据库中,然后停止该过程。gen_servers 在他们的主管中被认为是暂时的,所以它们不会重新启动,直到有东西再次需要它们。
问题从这里开始:如果我在代表 {car, 23} 的进程中的 handle_info 的保存步骤期间用它的键调用一个进程,比如 {car, 23},我会按预期取回 pid,因为过程正在保存且未完成。所以我会用 gen_server:call 调用我的进程,但我永远不会有响应(并达到默认的 5 秒超时),因为进程正在停止。(问题一)
为了解决这个问题,进程可以从全局注销自己,然后保存它的状态,然后停止。但是,如果我在注销后但在保存完成之前需要它,我将加载一个新进程,该进程可能会在数据库中加载未更新的值。(问题 B)
为了再次解决这个问题,我可以确保数据库中的加载和保存被排队并且不能并发。这可能是一个瓶颈。(问题 C)
我正在考虑另一种解决方案:我的进程在保存之前可以告诉 pidstore 他们很忙。pidstore 将保留一个繁忙进程的列表,并对这些键的任何需求做出“忙碌”响应。保存完成后,进程将告诉 pidstore no_more_busy 并在询问密钥时启动新进程。(即使旧的过程没有完成,它已经完成保存,所以它可以花时间独自死去)。
这对我来说似乎有点混乱,但是尝试多次从密钥中获取 Pid 感觉更简单,而不是包装对 gen_server 的每次调用以处理可能的超时。(当流程完成但仍在全球注册时)。
我对所有这些半问题和半解决方案有点困惑。您在这种情况下使用的设计是什么,或者我该如何避免这种情况?
我希望我的信息清晰易读,也请告诉我英文错误。
谢谢你