My GenStage can not start without register name, even I set name is atom or string.
Its worked with register name is MODULE only.
but I need dynamic register name to start multiple process
My GenStage can not start without register name, even I set name is atom or string.
Its worked with register name is MODULE only.
but I need dynamic register name to start multiple process
Can you share some code how you try to start your GenServer
?
Please keep in mind that names have to be atoms or (tagged) tupples where the tag is allowed to be :global
or :via
, while the {:global, name}
is just erlang sugar for {:via, :global, name}
.
I’m using libcluster and swarm for distribute nodes.
My app start with: App.Registry and a lot of children.
Each child is App.Wrapper has registe Genstage Supervisor. Each Genstage Supervisor contain: producer, producer_consumer, … and consumer (linked as pipeline).
That why I need start duplicate producer_consumer or consumer
Nothing of what you wrote answers my question. Even worse, there are no hints to GenServer
s anymore in your latest response.
MyApp:
children = Enum.map(args, fn [x] ->
name = Helpers.App.get_name_from_config_exs(x)
Supervisor.child_spec({App.Wrapper, {name, x}}, id: name)
end)
children = [worker(App.Registry, [])] ++ children
opts = [strategy: :one_for_one, name: __MODULE__]
Supervisor.start_link(children, opts)
App.Registry:
def start_via_swarm({name, config_exs}, reason \\ "starting") do
Logger.debug("[App.Registry] #{reason} via swarm: #{name}")
Swarm.register_name(name, App.Supervisor, :register, [{name, config_exs}])
end
App.Supervisor:
use Supervisor
def start_link({name, config_exs}) do
Logger.debug "[App.Supervisor] start Supervisor: #{name}"
GenServer.start_link(__MODULE__, {name, config_exs}, name: name)
end
def init({name, config_exs}) do
import Supervisor.Spec, warn: false
children = config_exs
|> Code.eval_file()
|> elem(0)
opts = [strategy: :one_for_one]
Supervisor.start_link(children, opts)
App.Registry.monitor(self(), name)
{:ok, name}
end
config_exs:
import Supervisor.Spec, warn: false
[
worker(AA,
[0]),
worker(BB,
[{{AA, min_demand: 1, max_demand: 10}, 2}]),
worker(CC,
[{{BB, min_demand: 1, max_demand: 10}, :ok}])
]
one of job:
defmodule BB do
use GenStage
def start_link({subscription, init_state}) do
GenStage.start_link(__MODULE__, {subscription, init_state}, name: __MODULE__)
end
def init({subscription, number}) do
{:producer_consumer, number, subscribe_to: [subscription]}
end
def handle_events(events, _from, number) do
# If we receive [0, 1, 2], this will transform
# it into [0, 1, 2, 1, 2, 3, 2, 3, 4].
events =
for event <- events,
entry <- event..event+number,
do: entry
# IO.inspect(events, label: "BB")
{:noreply, events, number}
end
end
Error in the above job when I try remove or change (using string or atom) name: MODULE
Supervisor or GenServer? Also where does name
come from? How is it generated?
Updated in the source code of MyApp
name is string generated from path of app_config.exs
As I already said, name has to be an atom or a {:global, name}
or a {:via, registry, name}
tuple.
At least for the calls to GenServer
.
And again, what is your module? Shall it be a Supervisor
(thats what you make it via use Supervisor
) or a GenServer
(which you ask it for by doing GenServer.start_link
.
It seems as if there is more than only the name thing going on.
I try atom or {:global, name} or remove but its doesn’t work
My module is GenStage, and this is what I see in GenServer.start_link:
@spec start_link(module, term, GenServer.options()) :: GenServer.on_start()
def start_link(module, args, options \\ []) when is_atom(module) and is_list(options) do
GenServer.start_link(__MODULE__, {module, args}, options)
end
the error:
** (Mix) Could not start application my_app: MyApp.start(:normal, [["lib/components/app_event/app_config.exs"]]) returned an error: shutdown: failed to start child: :app_event
** (EXIT) shutdown: failed to start child: EventParser
** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
And this is just another new line of code you haven’t shown previously.
From the code you have shown earlier, I’m still convinced that your App.Supervisor
is a problem, as it mixes a use Supervisor
with a GenServer.start_link
.
So can you please give us a link to the project itself or recreate the issue in an example project published at github, that we can take a closer look?
You need to rename all references to BB
then.
diff --git a/lib/components/demo_pipeline/app_config.exs b/lib/components/demo_pipeline/app_config.exs
index e545203..23a8345 100644
--- a/lib/components/demo_pipeline/app_config.exs
+++ b/lib/components/demo_pipeline/app_config.exs
@@ -9 +9 @@ import Supervisor.Spec, warn: false
- [{{BB, min_demand: 1, max_demand: 10}, :ok}])
+ [{{:bb, min_demand: 1, max_demand: 10}, :ok}])
diff --git a/lib/components/demo_pipeline/bb.ex b/lib/components/demo_pipeline/bb.ex
index cee3cd0..503990d 100644
--- a/lib/components/demo_pipeline/bb.ex
+++ b/lib/components/demo_pipeline/bb.ex
@@ -4,2 +4,2 @@ defmodule BB do
- def start_link({subscription, init_state}) do
- GenStage.start_link(__MODULE__, {subscription, init_state}, name: __MODULE__)
+ def start_link({subscription, init_state}) do
+ GenStage.start_link(__MODULE__, {subscription, init_state}, name: :bb)
@@ -24 +24 @@ defmodule BB do
-end
\ No newline at end of file
+end
Then it works on my machine…
Its worked, thank you so much