shahryarjb

shahryarjb

How to restart a genserver under DynamicSupervisor which is started under PartitionSupervisor

Hello friends, I think I am creating a bad config for my project.

I have a genserver is started under DynamicSupervisor and I start it with PartitionSupervisor

my Application config:

  def start(_type, _args) do
    children = [
      {Registry, keys: :unique, name: MishkaJobWorkerRegistry},
      {PartitionSupervisor, child_spec: DynamicSupervisor, name: MishkaJobWorkerSupervisor},
    ]

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

It is my Genserver simple code:

defmodule Queue.Job do
  use GenServer
  require Logger
  
  def start_link(args) do
    id = Map.get(args, :worker)
    type = Map.get(args, :type, :normal)

    GenServer.start_link(__MODULE__, [], name: via(id, type))
  end

  @impl true
  def init(state \\ %{}) do
    {:ok, state}
  end
  
  @doc false
  def child_spec(process_name) do
    %{
      id: __MODULE__,
      start: {__MODULE__, :start_link, [process_name]},
      restart: :transient,
      max_restarts: 4
    }
  end

  defp via(id, value) do
    {:via, Registry, {MishkaJobWorkerRegistry, id, value}}
  end
end

and I start like this:

  def start_job_worker(args) do
    DynamicSupervisor.start_child(
      {:via, PartitionSupervisor, {MishkaJobWorkerSupervisor, self()}},
      {Queue.Job, args}
    )
  end

But if my genserver crashes unexpectedly, it does not reset it and when I check the process of my genserver , it returns false.

Another problem is

when I use this to terminate one of genserver by pid, it returns not found

DynamicSupervisor.terminate_child(MishkaJobWorkerSupervisor, pid)

Where I am creating a bug?

Thank you in advance

Marked As Solved

alisinabh

alisinabh

when I use this to terminate one of genserver by pid, it returns not found

DynamicSupervisor.terminate_child(MishkaJobWorkerSupervisor, pid)

Where I am creating a bug?

The problem is that you are referencing the wrong name here. MishkaJobWorkerSupervisor is not the name that you should use. If you pay close attention to how the process is started here you can see that the :via tuple has been used. To terminate the child, you need to use the same via tuple.

  def start_job_worker(args) do
    DynamicSupervisor.start_child(
      {:via, PartitionSupervisor, {MishkaJobWorkerSupervisor, self()}},
      {Queue.Job, args}
    )
  end

So to terminate you can do something like

DynamicSupervisor.terminate_child(
  {:via, PartitionSupervisor, {MishkaJobWorkerSupervisor, self()}}, 
  # Remember that because you used self() for the partition key, you need to call this from the same process or replace self() with the correct pid.
  pid
)

Also Liked

al2o3cr

al2o3cr

This line is the problem - MishkaJobWorkerSupervisor is the PartitionSupervisor, so the PID isn’t found because it’s a child of one of the supervisor’s children.

The call doesn’t crash because DynamicSupervisor.terminate_child sends a {:terminate_child, pid} message, which is handled by the machinery for :supervisor.terminate_child.

To accurately target the message, you need to use a :via tuple pointing to the PartitionSupervisor:

{:via, PartitionSupervisor, {MishkaJobWorkerSupervisor, self()}}

HOWEVER

If the process that’s calling terminate_child isn’t the same one that started the child, I’m not sure that’s going to find the correct DynamicSupervisor. :thinking:

Where Next?

Popular in Questions Top

bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
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
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
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
mathew4509
I have a list say x = ["23gh", "56kh", "97mh"] I would like to pass each element to Val in each iteration. Say, in iteration 1 -------...
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
wernerlaude
In AR this is so simple @articles = current_user.articles How to do in Ecto? def index(conn, _params) do current_user = conn.assig...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
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
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
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