如何将参数传递给gen_server函数?

时间:2016-07-14 16:16:40

标签: parameters erlang otp gen-server

我有一个gen_server,每次调用increment()函数时都会递增计数器。

-module(genserver).
-export([start_link/0, start/0, increment/0]).
-behaviour(gen_server).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

init([]) ->
    {ok, "counter.txt"}.

start() ->
    gen_server:start({local, ?MODULE}, ?MODULE, [], []).

increment() ->
    gen_server:call(?MODULE, increment).

handle_call(increment, _From, File) ->
    Counter = case file:read_file(File) of
        {ok, Binary} -> binary_to_integer(Binary);
        {error, enoent} -> 0
    end,
    ok = file:write_file(File, integer_to_binary(Counter + 1)).

handle_cast(_Req, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

这是shell执行示例

Eshell V7.3  (abort with ^G)
1> c("C:/Users/guga.melkadze/Desktop/testgen"). 
{ok,testgen}
2> testgen:start().
{ok,<0.39.0>}
3> testgen:increment().
920
4> testgen:increment().
921
5> testgen:increment().
922

现在每次调用genserver:increment()方法时我都需要发送一个参数。例如genserver:increment(someParameter)。我如何实现这一目标?

1 个答案:

答案 0 :(得分:3)

更改increment函数以发送元组而不仅仅是原子:

increment(N) ->
    gen_server:call(?MODULE, {increment, N}).

并更新handle_call子句以使用它:

handle_call({increment, N}, _From, File) ->
    Counter = case file:read_file(File) of
        {ok, Binary} -> binary_to_integer(Binary);
        {error, enoent} -> 0
    end,
    ok = file:write_file(File, integer_to_binary(Counter + N)).

请注意,您的handle_call函数不会返回gen_server行为所期望的值类型,因此在每次请求后此过程可能会崩溃。你应该添加这样的东西作为最后一行:

{reply, ok, File}.