owaisqayum

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

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 :wink:

Also Liked

gregvaughn

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

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.

Where Next?

Popular in Questions Top

pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
New
Werner
Hi, I’m using Ubuntu 18.04 and after updating to OTP-24.0 yesterday i have this warning when I run “mix local.hex”: 14:57:30.512 [warn] ...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
idi527
I’ve been re-reading swift book again and noticed that multiline strings there don’t have a trailing line break, unlike in elixir iex(2)...
New

Other popular topics Top

JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1140 51847 244
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

We're in Beta

About us Mission Statement