evbruno

evbruno

Issue with Horde / HordeRegistry with elixir 1.18

Hi folks, I’m trying the simple SayHello example from the Horde docs, but I can’t get it to work.

I can start a child with:

Horde.DynamicSupervisor.start_child(
  HelloClusterApp.HelloSupervisor, 
  {HelloClusterApp.SayHello, name: "say_hello_1"}
)

I can also lookup on both nodes, and the process is actually there:

iex(foo@jotumhein)> Horde.Registry.lookup(HelloClusterApp.HelloRegistry, "say_hello_1")
[{#PID<24805.479.0>, nil}]

and:

iex(bar@jotumhein)> Horde.Registry.lookup(HelloClusterApp.HelloRegistry, "say_hello_1")
[{#PID<0.479.0>, nil}]

But I can’t figure it out how to send a message.

I’m trying:

GenServer.call({:via, Horde.Registry, {HelloClusterApp.HelloRegistry, "say_hello_1"}}, :action)

.. but I always get this error (running on the same node or not):

** (exit) exited in: GenServer.call({:via, Horde.Registry, {HelloClusterApp.HelloRegistry, "say_hello_1"}}, :action, 5000)
    ** (EXIT) an exception was raised:
        ** (Protocol.UndefinedError) protocol String.Chars not implemented for type Tuple. This protocol is implemented for the following type(s): Atom, BitString, Date, DateTime, Float, Integer, List, NaiveDateTime, Time, URI, Version, Version.Requirement

Got value:

    {#PID<0.219.0>, [:alias | #Reference<0.0.28035.3569112820.221577217.43273>]}

            (elixir 1.18.4) lib/string/chars.ex:3: String.Chars.impl_for!/1
            (elixir 1.18.4) lib/string/chars.ex:22: String.Chars.to_string/1
            (hello_cluster_app 0.1.0) lib/hello_cluster_app/say_hello.ex:37: HelloClusterApp.SayHello.handle_call/3
            (stdlib 6.2.2.1) gen_server.erl:2381: :gen_server.try_handle_call/4
            (stdlib 6.2.2.1) gen_server.erl:2410: :gen_server.handle_msg/6
            (stdlib 6.2.2.1) proc_lib.erl:329: :proc_lib.init_p_do_apply/3
    (elixir 1.18.4) lib/gen_server.ex:1128: GenServer.call/3
    iex:13: (file)

11:58:14.039 [error] GenServer {HelloClusterApp.HelloRegistry, "say_hello_1"} terminating
** (Protocol.UndefinedError) protocol String.Chars not implemented for type Tuple. This protocol is implemented for the following type(s): Atom, BitString, Date, DateTime, Float, Integer, List, NaiveDateTime, Time, URI, Version, Version.Requirement

Got value:

    {#PID<0.219.0>, [:alias | #Reference<0.0.28035.3569112820.221577217.43273>]}

    (elixir 1.18.4) lib/string/chars.ex:3: String.Chars.impl_for!/1
    (elixir 1.18.4) lib/string/chars.ex:22: String.Chars.to_string/1
    (hello_cluster_app 0.1.0) lib/hello_cluster_app/say_hello.ex:37: HelloClusterApp.SayHello.handle_call/3
    (stdlib 6.2.2.1) gen_server.erl:2381: :gen_server.try_handle_call/4
    (stdlib 6.2.2.1) gen_server.erl:2410: :gen_server.handle_msg/6
    (stdlib 6.2.2.1) proc_lib.erl:329: :proc_lib.init_p_do_apply/3
Last message (from #PID<0.219.0>): :action
State: %{count: 0, init_args: ["say_hello_1"]}
Client #PID<0.219.0> is alive

    (stdlib 6.2.2.1) gen.erl:260: :gen.do_call/4
    (elixir 1.18.4) lib/gen_server.ex:1125: GenServer.call/3
    (elixir 1.18.4) src/elixir.erl:386: :elixir.eval_external_handler/3
    (stdlib 6.2.2.1) erl_eval.erl:919: :erl_eval.do_apply/7
    (elixir 1.18.4) src/elixir.erl:364: :elixir.eval_forms/4
    (elixir 1.18.4) lib/module/parallel_checker.ex:120: Module.ParallelChecker.verify/1
    (iex 1.18.4) lib/iex/evaluator.ex:336: IEx.Evaluator.eval_and_inspect/3
    (iex 1.18.4) lib/iex/evaluator.ex:310: IEx.Evaluator.eval_and_inspect_parsed/3

Same thing if running with GenServer.call(HelloClusterApp.SayHello.via_tuple("say_hello_1"), :action)


Extra info

I have created a new project scaffold with mix new hello_cluster_app --sup, and my build is:

$ elixir -v
Erlang/OTP 27 [erts-15.2.7] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [dtrace]

Elixir 1.18.4 (compiled with Erlang/OTP 26)

application.ex starts as:

def start(_type, _args) do
    topologies = [example: [strategy: Cluster.Strategy.Gossip]]

    children = [
      {Cluster.Supervisor, [topologies, [name: HelloClusterApp.ClusterSupervisor]]},
      {Horde.Registry, [name: HelloClusterApp.HelloRegistry, keys: :unique, members: :auto]},
      {Horde.DynamicSupervisor,
       [name: HelloClusterApp.HelloSupervisor, strategy: :one_for_one, members: :auto]}
    ]

    opts = [strategy: :one_for_one, name: HelloClusterApp.Supervisor]
    Supervisor.start_link(children, opts)
  end

say_hello.ex:

defmodule HelloClusterApp.SayHello do
  use GenServer
  require Logger

  def child_spec(opts) do
    name = Keyword.get(opts, :name, __MODULE__)

    %{
      id: "#{__MODULE__}_#{name}",
      start: {__MODULE__, :start_link, [name]},
      shutdown: 10_000,
      restart: :transient
    }
  end

  def start_link(name) do
    case GenServer.start_link(__MODULE__, [name], name: via_tuple(name)) do
      {:ok, pid} ->
        {:ok, pid}

      {:error, {:already_started, pid}} ->
        Logger.info("already started at #{inspect(pid)}, returning :ignore")
        :ignore
    end
  end

  @impl true
  def init(args) do
    state = %{count: 0, init_args: args}
    {:ok, state}
  end

  def via_tuple(name), do: {:via, Horde.Registry, {HelloClusterApp.HelloRegistry, name}}

  @impl true
  def handle_call(msg, from, state) do
    IO.puts("Handling call: #{from} => #{inspect(state)} => #{inspect(msg)}")
    {:reply, :foo, state}
  end

  @impl true
  def handle_info(msg, state) do
    IO.puts("Handling info: #{inspect(state)} => #{inspect(msg)}")
    {:noreply, state}
  end
end

Most Liked

evbruno

evbruno

OMFG!

I wrote this last night while not fully awake and I missed that! shame on me!

Thank you so much!

ps: having a little of time to inspect the stack trace, the error message was clear and I didn’t pay enough attention to it:

                (elixir 1.18.4) lib/string/chars.ex:22: String.Chars.to_string/1
--->            (hello_cluster_app 0.1.0) lib/hello_cluster_app/say_hello.ex:37: HelloClusterApp.SayHello.handle_call/3
                (stdlib 6.2.2.1) gen_server.erl:2381: :gen_server.try_handle_call/4
nerdyworm

nerdyworm

Pretty sure you’ll just need to add an inspect(from) to your handle_call function:

IO.puts(“Handling call: #{from} => #{inspect(state)} => #{inspect(msg)}”)

Where Next?

Popular in Questions Top

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
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

We're in Beta

About us Mission Statement