Hi, I have a normal Genserver which has a normal Supervisor and it’s Supervisor has a DynamicSupervisor and Registry like this:
Genserver1 -> Supervisor -> DynamicSupervisor
I have a problem, when I want to stop a PID
and delete it’s Registry. when I call Genserver1.stop
like this.
@impl true
def handle_cast(:stop, stats) do
Logger.info("OTP ACL server was stoped and clean State")
{:stop, :normal, stats}
end
it is just restrated and DynamicSupervisor.start_child
is loaded again, and the default data and this PID’s Registry still exists.
please help me , thanks
Try setting the restart
option to :transient
or :temporary
when starting a child
. See DynamicSupervisor.start_child/2
EDIT: I see now that you use a normal Supervisor to start the GenServer. The same still applies that you shoud add restart
to the child spec when starting the GenServer
Otherwise the process will get restarted
From iex> h Supervisor
Restart values (:restart)
The :restart option controls what the supervisor should consider to be a
successful termination or not. If the termination is successful, the supervisor
won’t restart the child. If the child process crashed, the supervisor will
start a new one.
The following restart values are supported in the :restart option:
• :permanent - the child process is always restarted.
• :temporary - the child process is never restarted, regardless of the
supervision strategy: any termination (even abnormal) is considered
successful.
• :transient - the child process is restarted only if it terminates
abnormally, i.e., with an exit reason other than :normal, :shutdown, or
{:shutdown, term}.
2 Likes
hi, I did this before use Supervisor, restart: :temporary or transient
in my Supervisor
not DynamicSupervisor
I think my DynamicSupervisor can let me stop it and delete it’s Registry
this line
def start_job(args) do
DynamicSupervisor.start_child(MishkaUser.Acl.AclOtpRunner, {MishkaUser.Acl.AclSupervisor, args})
end
I don’t understand what to do !!
Are you able to share the relevant code? I.e where you start your DynamicSupervisor, your Supervisor and your GenServer?
Also, I am not sure about the strategy you are using with: DynamicSupervisor → Supervisor → GenServer?
Are you starting up dynamic supervision trees? But you register GenServers under the Supervisor?
Yes I think, I implemented Genserver under supervisor and implemented supervisor under dynamic supervisor
Thanks, I will have a look at the code.
A first thought is that I am not sure you need the Supervisor in the middle? Why not start the GenServers directly through the DynamicSupervisor?
2 Likes
before this post, I thought I can handle direct Supervisors with their code and strategy, and handle it on DynamicSupervisor (like 2 or 3 supervisor), I think it is wrong and I don’t know why I decided to do this
and I changed this now
def start_job(args) do
DynamicSupervisor.start_child(MishkaUser.Acl.AclOtpRunner, {MishkaUser.Acl.AclManagement, args})
end
I load Genserver direct in my DynamicSupervisor, but still after stop Genserver PID it restart me again and import default value
I think now I can use
DynamicSupervisor.terminate_child(DynamicSupervisor_module_name, pid)
after use this, I cant find the process was killed .
Either you need to add the restart
option in start_child
or your GenServer
should have use GenServer, restart: :temporary
child_spec = Supervisor.child_spec({MishkaUser.Acl.AclManagement, args}, restart: :temporary)
DynamicSupervisor.start_child(MishkaUser.Acl.AclOtpRunner, child_spec)
1 Like
Should work.
[{pid, _}] = Registry.lookup(YourRegistryName, user_id)
DynamicSupervisor.terminate_child(MishaUser.Acl.AclOtpRunner, pid)
2 Likes