在初始化Erlang主管进程时添加gen_event处理程序

时间:2019-04-19 03:23:46

标签: erlang supervisor gen-event

我正在学习Erlang,并且正在设法相对有效地找到答案并为大多数问题制定解决方案,但是花了无法接受的时间来解决这个问题:

将处理程序添加到主管进程正在启动的gen_event模块的正确方法是什么?到目前为止,在我的探索中,我已经能够设置进程,gen_servers,supervisor(启动gen_servers)和gen_event模块,但是实际上我尝试向gen_event添加处理程序的所有操作都使我的supervisor进程崩溃了,甚至有时我的壳!

主管模块:

-module(sup).
-behaviour(supervisor).

%% API
-export([start_link/0, init/1]).
-export([stop/0]).

start_link() ->
  supervisor:start_link({local, ?MODULE}, ?MODULE, []).

init(_) ->
  EventServerSpec = #{
    id => osc_event_server,
    start => {gen_event, start_link, [{local, osc_server}]},
    modules => dynamic
  },
  ChildSpecList = [EventServerSpec, child(frequency), child(bkpt_server)],
  SupFlags = #{strategy => rest_for_one,
    intensity => 2, period => 3600},
  {ok, {SupFlags, ChildSpecList}}.

child(Module) ->
  #{id => Module,
    start => {Module, start_link, []},
    restart => permanent,
    shutdown => 2000,
    type => worker,
    modules => [Module]}.

…和gen_event模块osc_event_server的一些点点滴滴(希望是有关的部分!)

...
init([]) ->
  {ok, Socket} = gen_udp:open(8980, [binary, {active, false}]),
  {ok, #{socket => Socket, target_port => get_target_port()}}.

...
handle_event({send_osc, Path, Data}, State) ->
  TargetPort = maps:get(target_port, State),
  Socket = maps:get(socket, State),
  sendMessage(Socket, TargetPort, Path, Data),
  {ok, State};
...

据我对gen_event行为的了解很差,我对运行包含以下代码段的代码的结果并不感到惊讶:

  • 它启动时不会崩溃
  • 它启动gen_event并为其生成可引用的Pid,但从未命中'osc_event_server'的init
  • gen_event没有附加实际的事件处理程序。 “ which_handlers”和尝试发送消息都可以确认这一点。

我想结合的两件事:

  1. 将特定的事件处理程序(例如“ send_osc”)附加到我的gen_event进程中……希望从主管代码中进行
  2. 将初始化参数传递给osc_event_server模块;我希望至少能够指定UDP服务器的端口(而不是硬接线“ 8980”),并提供我的进程要与之通信的远程UDP服务器的IP +端口。

非常感谢。随意批评您所看到的一切……例如,我的整个方法:)至此,我已经了解了很多Erlang,与我误解的Erlang数量相比,我相信这没什么。

1 个答案:

答案 0 :(得分:1)

您应该将gen_event进程视为节点上存在的一种服务。通常,您会给它起一个名字,然后使用该名字与它交谈。除非您这样做,否则它只是一段独立的代码。

这意味着,如果您想添加处理程序,鉴于您无法在主管内运行任意代码来执行此操作,那么最简单的方法是让主管在之后生成同级进程 gen_event进程已准备就绪。

将新的兄弟姐妹标记为transienttemporary,让它成为gen_serversupervisor_bridge的小助手,并为其指定名称{{1 }}。小工人应添加处理程序。然后,它可以出于gen_event的原因而关闭,或者在需要时监督处理程序,以防它们崩溃以重新添加它们。