我有一个Erlang"后端"包含很多进程。现在我正在准备一个基准测试文件,该文件将针对延迟进行测试,我希望在一个可以增加某些负载参数的循环内运行此测试。
我基本上有一个server:init()
函数启动主服务器管理器进程,然后我通过该管理器在服务器上注册N
个客户端。经理将为新注册的客户指定一个任意数据行为者流程。
这些数据参与者中的每一个都有多个客户端。我添加了一个小图表来说明我的意思。
+------------+
|Manager |
+------------++-----------+
+ + |
| | |
v v v
+-----+ +-----+ +-----+
| | | | | |
| Da 1| | Da 2| |Da N |
+-----+ +-----+ . . . +-----+
+ +
| |
| |
| |
+----+ | +----+ |
|c1.1|<---| |c2.1|<-|
| | | | | |
+----+ | +----+ |
| |
+----+ | +----+ |
|c1.2|<---+ |c2.2|<-+
| | | |
+----+ +----+
. .
. .
. .
我现在想要做的是运行服务器并在我的负载测试完成后终止所有进程。我似乎无法在同一erl
次重复中运行两次loadtest,因为某些进程仍在运行。 (注册(名称,)例如失败。)
我读过关于杀死进程here的内容,但对我来说,在像Erlang这样的语言中,没有更多的方法可以做到这一点,这似乎很奇怪。
我可以从该文件中得到的结论是,manager
必须向所有数据参与者发送信号以杀死他们自己,但在此之前,请杀死他们所有的客户端进程?即,传播消息并开始从我的树底向上杀死进程到我的经理。
看起来非常冗长,我想知道是否还有另一种方式。
到目前为止,我有以下内容:
当我的loadtest完成后,启动管理器进程的进程(shell)执行此操作:
exit() ->
unregister(data_actor_manager),
unregister(shell),
exit(data_actor_manager, normal).
但这导致了一个令人讨厌的错误:
{"init terminating in do_boot",{badarg,[{erlang,unregister,[data_actor_manager],[]},{server_single_actor,exit,0,[{file,"c:/Users/CHRIST~1/DOCUME~1/BITBUC~1/ERLANG~2/src/server_single_actor.erl"},{line,48}]},{load,start,0,[{file,"c:/Users/CHRIST~1/
CUME~1/BITBUC~1/ERLANG~2/src/load.erl"},{line,36}]},{init,start_it,1,[{file,"init.erl"},{line,1054}]},{init,start_em,1,[{file,"init.erl"},{line,1034}]}]}}
该错误意味着data_actor_manager
不是有效名称或Pid,但它是..
所以我尝试了以下内容。认为我可能不必取消注册与经理Pid相关联的原子,我尝试了这个:
exit() ->
exit(whereis(data_actor_manager), normal).
但是,我再次收到badarg
错误消息。
答案 0 :(得分:1)
Erlang / OTP主管行为似乎非常适合此问题:http://www.erlang.org/doc/design_principles/sup_princ.html和http://www.erlang.org/doc/man/supervisor.html
基本上,您可以设置一个监督树,它将从您的主服务器级联下来并处理您的客户端的终止和重启。