开发者

Erlang: extended gen_server

I want to extend gen_server (create a gen_server_extra) with some additional functionality. The requirements are:

  1. The gen_server_extra processes should behave like a regular gen_server's. E.g, they should accept calls via gen_server:call, integrate with SASL, fit OTC supervision tree, etc.
  2. gen_server_extra processes should have an additional functionality, provided by gen_server_extra. That basically means some of the messages will be handled by gen_server_extra code, without passing them to the callback module. The rest of the messages are 开发者_StackOverflowpassed to callback module as is.
  3. gen_server_extra functionality requires its own state which should be hidden from the callback module.

What is the simplest approach to do that?


The best, most modular approach would be to implement a new behavior in a module (e.g. gen_ext_server) and wrap the gen_server behavior from there.

First, make sure your behavior is identical to gen_server:

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

% Exports...

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

Implement all callbacks needed for gen_server, keep the name of the callback module that implements your behavior in your state:

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

Then, in each gen_server callback, implement your behavior and then call the callback module if needed:

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.

Implement similar functionality for handle_cast/2, handle_info/2, terminate/1 etc.


well, i would not call it customization, but rather a new behavior. You need to define your own behavior. A tutorial which will take you through this is found at trapexit.org.
However, the requirements are not very proper.

The main essence of giving the call back functions access to the server state is to write normal sequential code manipulating the state of your application when and where you want without interrupting the concurrency details. Otherwise if that is the way to go, implement your own behavior.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜