3

I am trying to learn Erlang and OTP, and so I am currently trying to get a handle on gen_server.

I wrote a quick gen_server implementation of:

-module(test). -behavior(gen_server). %% API -export([start/0, add/1]). -export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2]). start() -> gen_server:start_link(?MODULE, [], []). add(Value) -> gen_server:call(self(), {add, Value}). %% Gen_Server init(_Arguments) -> {ok, []}. terminate(_Reason, _State) -> ok. code_change(_PreviousVersion, State, _) -> {ok, State}. handle_call({add, Value}, _From, State) -> {reply, ok, [Value|State]}. handle_cast(_Arg0, State) -> {noreply, State}. handle_info(Info, State) -> io:format("Unexpected message: ~p~n",[Info]), {noreply, State}. 

The problem with this is the add/1 call is timing out instead of returning ok:

1> {ok, Pid} = test:start(). {ok,<0.33.0>} 2> Pid ! abc. Unexpected message: abc abc 3> test:add(3). ** exception exit: {timeout,{gen_server,call,[<0.31.0>,{add,3}]}} in function gen_server:call/2 (gen_server.erl, line 204) 4> Pid ! abc. abc 

What am I doing wrong? It looks like the server is no longer running when I run gen_server:call/2.

1 Answer 1

4

You are passing in self() as the pid for the gen_server in test:add, that's not correct. self() will evaluate to the pid of the REPL process you are in when making the call.

You can simply add the gen_server pid as a parameter to test:add, since you get it from test:start().

Sign up to request clarification or add additional context in comments.

2 Comments

Why is that bad? Wouldn't I want the REPL to receive the reply from the gen_server so I can verify the reply in the REPL?
Oh I see, I'm totally misunderstanding what the first parameter of gen_server:call/2! I mis-interpreted the switch from non-gen_server to gen_server chapters in LYSE.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.