【发布时间】:2020-09-06 14:40:34
【问题描述】:
在我的应用程序中,所有登录的用户都由GenServer 表示,我称之为UserAgent,它基本上将每个用户的状态保存在内存中。所有这些进程都在基于Horde 的分布式注册表中跨集群注册,并具有唯一的ID。每当用户执行某些操作时,客户端应用程序都会将要执行的操作与user_id 一起发送。在服务器端,控制器检查参数(强制、可选、语法等)并最终调用UserAgent.the_action(user_id, other_params)。 the_action(...) 函数只是向服务器发送一条消息,其中包含要执行的操作:GenServer.call(via_tuple(id), {:the_action, params})。
在某些情况下,user_id 引用的 UserAgent 不再存在,例如,因为用户已经不活动一段时间并且进程已被清除(会话已过期)或因为部分此时无法访问集群的一部分(目前的虚构用例)。在这些情况下,调用GenServer.call(via_tuple(id), {:the_action, params}) 会导致下面的错误,这也会导致HTTP 端点进程(下面的#PID<0.1359.0>)崩溃,进而导致500 HTTP 错误(dump api 调用,嗯,转储状态用于调试目的的进程):
[error] #PID<0.1359.0> running AppWeb.Endpoint (connection #PID<0.1358.0>, stream id 1) terminated
Server: localhost:4001 (http)
Request: GET /api/v1/dump/5f534b99d6ca3fe1ff6d2f78
** (exit) exited in: GenServer.call({:via, Horde.Registry, {App.DReg, "5f534b99d6ca3fe1ff6d2f78"}}, :dump, 5000)
** (EXIT) no process: the process is not alive or there's no process currently associated \
with the given name, possibly because its application isn't started
我只是不知道如何拦截这个错误。实际上,我最终在UserAgent 的客户端部分调用Horde.Registry.lookup(App.UserAgent.via_tuple(user_id)),然后调用GenServer.call() with the returned pid`,或者如果找不到进程,则向控制器返回错误。
我想知道是否有更好的方法。
【问题讨论】:
标签: elixir