'handle_call' getting timed out
Asked Answered
G

1

8

i am calling elixir genserver from handle info function in GenServer to add phone-number getting form client. But as soon as handle_call is called owner process gets crashed [timeout]. Please help.

One ETS is created globally to insert values already before any below stated function is called.

def handle_info(message, state) do

    {a,b} = message
    phonenumber = b[:body] 
    add phonenumber
    {:noreply, state}
end

def add(phonenumber) do
    GenServer.call(__MODULE__, {:add, phonenumber})
end


def handle_call({:add, phonenumber}, from, state) do

    :ets.insert(:access_table, {:details, phonenumber})
    reply = {:ok, "Added #{phonenumber} to profile"}
    new_state = [{username} | state]
    {:reply, reply , new_state}
end

Error:

** When Server state == []
** Reason for termination == 
** {timeout,{gen_server,call,['Elixir.Bankrecord',{add,"346534543534"},5000]}}
** (EXIT from #PID<0.150.0>) exited in: :gen_server.call(Bankrecord, {:add, '346534543534'}, 5000)
** (EXIT) time out
Gallman answered 8/8, 2014 at 1:57 Comment(0)
C
7

You can't call yourself from within a call, as in your handle_info invoking add which performs a call back on your gen_server. Since all operations happen sequentially in a gen_server, you end up blocking on yourself. The solution should be to use a simple private add function on the module and have both handle_info and handle_call({:add delegate to it.

def add(phonenumber) do
  GenServer.call(__MODULE__, {:add, phonenumber})
end

def handle_info({_, message}, state) do
  add_number message[:body]
  {:noreply, state}
end


def handle_call({:add, phonenumber}, from, state) do
  add_number phonenumber
  {:reply, {:ok, "Added #{phonenumber} to profile"} , [{username} | state]}
end

defp add_number(phonenumber) do
  :ets.insert(:access_table, {:details, phonenumber})
end
Checkrow answered 8/8, 2014 at 2:24 Comment(4)
Thanks Chris, is it possible for you to share some code sample of resolution to my problem as i am newbee in elixir. Much Appreciated.Gallman
I added an example with the function delegationCheckrow
Works like charm, still one last query Chris [if you could help]. Just thinking how can i send the reply back to client with updated list of phone numbers from ETS using handle_call, when my handle_info does not return anything. Just bit confused to understand the flow of genserver.Gallman
You probably want the reply/2 elixir-lang.org/docs/stable/elixir/GenServer.html#reply/2Aun

© 2022 - 2024 — McMap. All rights reserved.