owaisqayum
How do i call handle_call outside module?
I have defined a module GS where genserver will be used and I need to create tables. I have the whole logic of the program In another module named base. How do I inherit handle_call in my genserver GS module ?
GS MODULE:
defmodule GS do
use GenServer
@name gen
# client
def start_link(opts \\ []) do
GenServer.start_link(__MODULE__, [], opts ++ [name: gen])
end
def creating_tables(tables_list) do
GenServer.call(@name, {:creating_tables, tables_list})
end
# server
def init(initial_state) do
{:ok, initial_state}
end
end
BASE MODULE
defmodule Base do
def handle_call({:creating_tables}, _from, state_tables_list) do
tables = Enum.map(state_tables_list, fn table -> create(table) end)
{:reply, tables, state_tables_list}
end
defp create(table) do
try do
:ets.new(table, [:named_table, :bag])
rescue
ArgumentError -> table
end
end
end
Marked As Solved
Laetitia
In this case, keep the handle_call function in GS. The Base module is a TableCreator (surely, you can find a better name)
defmodule TableCreator do
def create_tables(tables) when is_list(tables) do
tables |> Enum.map(fn table -> create(table) end)
end
defp create(table) do
try do
:ets.new(table, [:named_table, :bag])
rescue
ArgumentError -> table
end
end
end
and in the genserver module the function handle_call would be
def handle_call({:creating_tables}, _from, state_tables_list) do
tables = TableCreator.create_tables(state_tables_list)
{:reply, tables, state_tables_list}
end
i hope it helps ![]()
Also Liked
gregvaughn
I agree with @Laetitia and will add that handle_call and the tuple it returns is your contract with GenServer. That logic belongs in the GenServer callback module. But you can certainly call out to shared logic in another module in the body of the function.
I’d also caution you about bottlenecking your system. You seem to want to make it easy to create multiple ets tables. Those are owned by a process for lifecycle management purposes and you’re not making them public (nor are you accepting a parameter to do so) so all access will have to go through a single GenServer, which only handles a single message at a time.
lud
You must define handle_call/3 in the module you give to GenServer.start_link/3.
Your code:
GenServer.start_link(__MODULE__, [], opts ++ [name: gen])
Here you give __MODULE__, so you give GS.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








