Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chapter 3 - Calling get_count #4

Open
minostro opened this issue Jun 16, 2014 · 3 comments
Open

Chapter 3 - Calling get_count #4

minostro opened this issue Jun 16, 2014 · 3 comments

Comments

@minostro
Copy link

Hi,

I'm following this book chapter by chapter, and so far I have enjoyed it a lot!. However, now I'm struggling with the get_count function. It seems that is not possible to call tr_server:get_count(). from telnet because this will cause a deadlock on the server side:

telnet localhost 1055
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
tr_server:get_count().
{timeout,{gen_server,call,[tr_server,get_count]}}
Connection closed by foreign host.

This makes sense to me, because handle_info is performing a call to tr_server:get_count() that performs a sync call to the server.

The thing that I don't understand is why when I'm calling get_count from the erlang console I get the same error:

13> tr_server:start_link(1055).
{ok,<0.76.0>}
14> tr_server:get_count().     
** exception exit: {timeout,{gen_server,call,[tr_server,get_count]}}
     in function  gen_server:call/2 (gen_server.erl, line 180)

The thing that makes more sad is the fact of why we define a get_count function if we cannot use it at all.

It would be great if you could help to understand this issue. I'm using the exact file from the repo, so I'm not introducing any noise.

Thanks,

@richcarl
Copy link
Member

A drawback of the simplistic way it's implemented is that the get_count()
function cannot be used until the server has accepted a connection. Until
that has happened, the init() function still hasn't returned, so the
gen_server isn't ready to accept any other requests yet. This sort of
problem is addressed in later chapters.

/Richard

On Mon, Jun 16, 2014 at 10:09 PM, Milton Inostroza Aguilera <
notifications@github.com> wrote:

Hi,

I'm following this book chapter by chapter, and so far I have enjoyed it a
lot!. However, now I'm struggling with the get_count function. It seems
that is not possible to call tr_server:get_count(). from telnet because
this will cause a deadlock on the server side:

telnet localhost 1055
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
tr_server:get_count().
{timeout,{gen_server,call,[tr_server,get_count]}}
Connection closed by foreign host.

This makes sense to me, because handle_info is performing a call to
tr_server:get_count() that performs a sync call to the server.

The thing that I don't understand is why when I'm calling get_count from
the erlang console I get the same error:

13> tr_server:start_link(1055).
{ok,<0.76.0>}
14> tr_server:get_count().
** exception exit: {timeout,{gen_server,call,[tr_server,get_count]}}
in function gen_server:call/2 (gen_server.erl, line 180)

The thing that makes more sad is the fact of why we define a get_count
function if we cannot use it at all.

It would be great if you could help to understand this issue. I'm using
the exact file from the repo, so I'm not introducing any noise.

Thanks,


Reply to this email directly or view it on GitHub
#4.

    /Richard

@minostro
Copy link
Author

Hi Richard,

Thanks for your reply!

I thought when you were returning from the init function, you were making a timeout:

init([Port]) ->
    {ok, LSock} = gen_tcp:listen(Port, [{active, true}]),
    {ok, #state{port = Port, lsock = LSock}, 0}.

So this timeout causes that the following code get executed:

handle_info(timeout, #state{lsock = LSock} = State) ->
    {ok, _Sock} = gen_tcp:accept(LSock),
    {noreply, State}.

So when you say: the get_count() function cannot be used until the server has accepted a connection. That means we are blocked waiting for gen_tcp:accept(LSock) returns something right?

Anyway, now I got the get_count method working by doing this (following your description):

  1. In erl, tr_server:start_link().
  2. In other console, connect via telnet and send any command (lists:reverse([3,2,1]))
  3. then in erl, I'm able to get a result when calling tr_server:get_count().

Thanks.

@tolyo
Copy link

tolyo commented May 30, 2017

@richcarl Thank you for the explanation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants