terminate supervisor from it's child process

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

terminate supervisor from it's child process

block.rxckin.beats@gmail.com
Hi

I'm writing udp server with supervision tree like below.

```
              (s1for1)      (1for1)     
server_sup - udp_sup -  |- udp_worker
                                       |- dtls_worker
                                       |- stun_worker
                                       |- srtp_worker
```

1. app opening UDP socket
2. server_sup spawn udp_sup process tree with that udp socket
3. udp_worker receives every packet from socket
4. udp_woker passing packet to other worker based on first byte demultiplexing


Question:

when timeout in udp_worker happen,
I wanna terminate all processes in udp_sup (including udp_sup)
so I tried shutdown udp_sup with calling `server_sup:terminate_child(pid)`
that's terminates but rises SUPERVISOR REPORT with shutdown_error.

I also tried one_for_all for udp_sup's childspec but I don't want to restart children because UDP socket already timeouted.

is there any way to terminate supervisor from it's child process ?
or any other recommended process architecture for UDP server ?

thanks
Jxck

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: terminate supervisor from it's child process

Vance Shipley
On Thu, Feb 14, 2019 at 11:52 AM [hidden email]
<[hidden email]> wrote:
> I'm writing udp server with supervision tree like below.
...
>               (s1for1)      (1for1)
> server_sup - udp_sup -  |- udp_worker
>                                        |- dtls_worker
>                                        |- stun_worker
>                                        |- srtp_worker

> is there any way to terminate supervisor from it's child process ?

Yes, exit the child and have the supervisor's restart strategy do it's job.

> or any other recommended process architecture for UDP server ?

You could set the restart strategy of the above udp_sup to be
'rest_for_one' which would kill all the other workers when it died.
However that would have the side effect of kill stun_worker and
srtp_worker when dtls_worker exited.

The right way is to have a seperate supervisor for
[dtls|stun|srtp]_worker as a sibling to udp_worker.


--
     -Vance
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: terminate supervisor from it's child process

block.rxckin.beats@gmail.com
Hi Vance

thanks for your advice !

> However that would have the side effect of kill stun_worker and srtp_worker when dtls_worker exited.
that's expected, because they share same socket which timeouted.

> Yes, exit the child and have the supervisor's restart strategy do it's job.
You could set the restart strategy of the above udp_sup to be 'rest_for_one' which would kill all the other workers when it died.

I don't wanna restart child workers, so make it `restart => temporary` in childspec.
but in that case, if udp_woker terminates, udp_sup doesn't terminate. only igore it.

make if make `restart => permanent` and sup flag like below

```
SupFlags = #{
      strategy  => rest_for_one, # same for one_for_all
      intensity => 0,
      period    => 1
},
```
that's terminates supervisor with ErrorReport with
reached_max_restart_intensity.

it's terminates all supervision tree include udp_sup as I expected
but I don't intent to restart, only shutdown like temporary :(


> The right way is to have a seperate supervisor for [dtls|stun|srtp]_worker as a sibling to udp_worker.

I think you mean like this.

udp_sup - udp_worker
               |- dtls_sup - dtls_woker
               .... (same for stun,srtp)

if udp_worker be temporary, udp_sup will ignore,
if udp_wokrer be permanent and intensity = 0, period = 1
udp_sup will terminate with error because of restart error (even if I don't intent to restart)


if I misreading something, please mention me.

thanks
Jxck








2019年2月14日(木) 15:53 Vance Shipley <[hidden email]>:
On Thu, Feb 14, 2019 at 11:52 AM [hidden email]
<[hidden email]> wrote:
> I'm writing udp server with supervision tree like below.
...
>               (s1for1)      (1for1)
> server_sup - udp_sup -  |- udp_worker
>                                        |- dtls_worker
>                                        |- stun_worker
>                                        |- srtp_worker

> is there any way to terminate supervisor from it's child process ?

Yes, exit the child and have the supervisor's restart strategy do it's job.

> or any other recommended process architecture for UDP server ?

You could set the restart strategy of the above udp_sup to be
'rest_for_one' which would kill all the other workers when it died.
However that would have the side effect of kill stun_worker and
srtp_worker when dtls_worker exited.

The right way is to have a seperate supervisor for
[dtls|stun|srtp]_worker as a sibling to udp_worker.


--
     -Vance

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: terminate supervisor from it's child process

Vance Shipley
On Thu, Feb 14, 2019 at 1:47 PM [hidden email]
<[hidden email]> wrote:

> I think you mean like this.
>
> udp_sup - udp_worker
>                |- dtls_sup - dtls_woker
>                .... (same for stun,srtp)
>
> if udp_worker be temporary, udp_sup will ignore,
> if udp_wokrer be permanent and intensity = 0, period = 1
> udp_sup will terminate with error because of restart error (even if I don't intent to restart)
>
>
> if I misreading something, please mention me.

No, I meant:

     udp_sup
          -> udp_worker
          -> proto_sup
               -> dtls_woker
               -> stun_worker
               -> srtp_worker


--
     -Vance
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: terminate supervisor from it's child process

block.rxckin.beats@gmail.com
> No, I meant:
>     udp_sup
>          -> udp_worker
>          -> proto_sup
>               -> dtls_woker
>               -> stun_worker
>               -> srtp_worker

in that case,
udp_worker can terminate proto_sup
but who terminate udp_sup ?

here is my PoC



2019年2月14日(木) 17:59 Vance Shipley <[hidden email]>:
On Thu, Feb 14, 2019 at 1:47 PM [hidden email]
<[hidden email]> wrote:
> I think you mean like this.
>
> udp_sup - udp_worker
>                |- dtls_sup - dtls_woker
>                .... (same for stun,srtp)
>
> if udp_worker be temporary, udp_sup will ignore,
> if udp_wokrer be permanent and intensity = 0, period = 1
> udp_sup will terminate with error because of restart error (even if I don't intent to restart)
>
>
> if I misreading something, please mention me.

No, I meant:

     udp_sup
          -> udp_worker
          -> proto_sup
               -> dtls_woker
               -> stun_worker
               -> srtp_worker


--
     -Vance

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: terminate supervisor from it's child process

Vance Shipley
On Thu, Feb 14, 2019 at 2:40 PM [hidden email]
<[hidden email]> wrote:

> > No, I meant:
> >     udp_sup
> >          -> udp_worker
> >          -> proto_sup
> >               -> dtls_woker
> >               -> stun_worker
> >               -> srtp_worker
>
> in that case,
> udp_worker can terminate proto_sup
> but who terminate udp_sup ?

No, udp_sup terminates proto_sup. Use a one_for_all strategy on
udp_sup. When udp_worker exits all the others are terminated by the
supervisors.

--
     -Vance
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: terminate supervisor from it's child process

block.rxckin.beats@gmail.com
in that case, is child of udp_sup "permanent" or "temporary" ?

if temporary, udp_sup seems ignore udp_worker's terminate, and proto_sup still alive.

if permanent, udp_sup try to restart child which I don't expected. and if *failed to restart* udp_sup will terminate.

so, you mean, "fail to restart permanent  udp_worker(which unexpected) will terminate udp_sup eventually in one_for_all" is correct way to terminate supervisor from its child?

thanks
Jxck

2019/02/15 2:09、Vance Shipley <[hidden email]>のメール:

> On Thu, Feb 14, 2019 at 2:40 PM [hidden email]
> <[hidden email]> wrote:
>>> No, I meant:
>>>    udp_sup
>>>         -> udp_worker
>>>         -> proto_sup
>>>              -> dtls_woker
>>>              -> stun_worker
>>>              -> srtp_worker
>>
>> in that case,
>> udp_worker can terminate proto_sup
>> but who terminate udp_sup ?
>
> No, udp_sup terminates proto_sup. Use a one_for_all strategy on
> udp_sup. When udp_worker exits all the others are terminated by the
> supervisors.
>
> --
>     -Vance
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: terminate supervisor from it's child process

block.rxckin.beats@gmail.com
I solved this problem by using linking workers.

          s_1_f_1
udp_sup -----  udp_worker_sup - udp_worker
                   |- dtls_worker_sup - dtls_worker
                   |- srtp_worker_sup - srtp_worker
                   |- stun_worker_sup - stun_worker

start udp_worker for single UDP socket,
and start dtls/srtp/stun workers in init() of udp_worker,
and udp_worker link with ever other workers.
if any worker terminates, ever other worker handling
same UDP socket will terminate.

no need to supervisor for single UDP socket
and terminate supervisor for socket closing.

thanks

Jxck


2019年2月15日(金) 8:23 <[hidden email]>:
in that case, is child of udp_sup "permanent" or "temporary" ?

if temporary, udp_sup seems ignore udp_worker's terminate, and proto_sup still alive.

if permanent, udp_sup try to restart child which I don't expected. and if *failed to restart* udp_sup will terminate.

so, you mean, "fail to restart permanent  udp_worker(which unexpected) will terminate udp_sup eventually in one_for_all" is correct way to terminate supervisor from its child?

thanks
Jxck

2019/02/15 2:09、Vance Shipley <[hidden email]>のメール:

> On Thu, Feb 14, 2019 at 2:40 PM [hidden email]
> <[hidden email]> wrote:
>>> No, I meant:
>>>    udp_sup
>>>         -> udp_worker
>>>         -> proto_sup
>>>              -> dtls_woker
>>>              -> stun_worker
>>>              -> srtp_worker
>>
>> in that case,
>> udp_worker can terminate proto_sup
>> but who terminate udp_sup ?
>
> No, udp_sup terminates proto_sup. Use a one_for_all strategy on
> udp_sup. When udp_worker exits all the others are terminated by the
> supervisors.
>
> --
>     -Vance

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions