Erlang: extended gen_server
I want to extend gen_server
(create a gen_server_extra
) with some additional functionality. The requirements are:
- The
gen_server_extra
processes should behave like a regulargen_server
's. E.g, they should accept calls viagen_server:call
, integrate with SASL, fit OTC supervision tree, etc. gen_server_extra
processes should have an additional functionality, provided bygen_server_extra
. That basically means some of the messages will be handled bygen_server_extra
code, without passing them to the callback module. The rest of the messages are 开发者_StackOverflowpassed to callback module as is.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.
精彩评论