4

我想用一些额外的功能来扩展gen_server(创建一个)。gen_server_extra要求是:

  1. 这些gen_server_extra进程的行为应该像一个常规gen_server的。例如,他们应该通过 接听电话gen_server:call,与 SASL 集成,适合 OTC 监督树等。
  2. gen_server_extra流程应该有一个额外的功能,由gen_server_extra. 这基本上意味着一些消息将由gen_server_extra代码处理,而不会将它们传递给回调模块。其余消息按原样传递给回调模块。
  3. gen_server_extra功能需要它自己的状态,应该对回调模块隐藏。

最简单的方法是什么?

4

2 回答 2

7

最好的、最模块化的方法是在一个模块(例如)中实现一个新的行为并从那里gen_ext_server包装这个行为。gen_server

首先,确保您的行为与以下内容相同gen_server

-module(gen_ext_server).
-behavior(gen_server).

% Exports...

behaviour_info(Type) -> gen_server:behaviour_info(Type).

实现所需的所有回调gen_server,将实现您的行为的回调模块的名称保留在您的状态中:

init([Mod|ExtraArgs]) ->
    % ...
    ModState = Mod:init(ExtraArgs),
    #state{mod = Mod, mod_state = ModState, internal = [...]}

然后,在每个gen_server回调中,实现您的行为,然后在需要时调用回调模块:

handle_call(internal, _From, State) ->
    % Do internal stuff...
    {reply, ok, State};
handle_call(Normal, From, State = #state{mod = Mod, mod_state = ModState}) ->
    case Mod:handle_call(Normal, From, ModState) of
        {reply, Reply, NewState} ->
            {reply, Reply, #state{mod_state = NewState};
        ... ->
            ...
    end.

handle_cast/2为,handle_info/2等实现类似的功能terminate/1

于 2011-07-19T10:52:41.917 回答
-1

好吧,我不会称之为定制,而是一种新的行为。您需要定义自己的行为。在 trapexit.org 上可以找到一个指导您完成此过程的教程。
但是,要求不是很合适。

让回调函数访问服务器状态的主要本质是编写正常的顺序代码,在您想要的时间和地点操作应用程序的状态,而不会中断并发细节。否则,如果这是要走的路,请实施您自己的行为。

于 2011-07-19T11:32:43.290 回答