"Chances are it is a less useful construction in Go"; (IMHO too) is correct 
- commonly speaking. Though I've had this observation that lots of 
repetitive code abstraction happens and still there is no one de-facto 
tool/lib/practice how tackle these.

Again I think nothing can be compared to Erlang/BEAM system. We have 
context package in Go, but again we have to write explicit code to use it. 
There is no runtime/builtin support for controlling goroutines implicitly. 
There is no actual concept of linking (two-way/monitoring) - I guess this 
is one aspects of CPS.

And for registration, even on BEAM, if someone does not know it's 
internals, it might bit her/him. Once I was writing a bot in Elixir and did 
not know that the number of atoms is limited. And I learnt the fact 
hardway; done through implementing a half baked registry, which would 
accept strings as identifiers (instead of atoms) and finally I've learnt 
about gproc. Though I admit (aside from being a dynamic language) Elixir 
feels simpler to work with.

Anyhow, I needed a cross-breed of context.Context & sync.WaitGroup (& a 
step further; a capped one; to implement a workerpool). There is errgroup, 
though primitive, is a good starting point.

So I've decided to see how it would look like to "mimic" Elixir supervisors 
(since, as you've explained, these two are fundamentally different), in a 
very simple form.

This supervisor has a list of child-descriptors (which acts as the 
registry) and restarts a child until it's intensity becomes zero; at which 
point it will get removed by assigning nil to it's slot - but not removed 
from the registry, since supervisor uses the index for housekeeping. And 
when there are no more active children, the supervisor would exit.

The supervisor does catch the panic chain, but again as you've mentioned, 
all clean-ups has to be explicit - neither Go is a declarative PL nor it's 
runtime provides any means to control a goroutine context from outside.

RestForOne is indeed hard to implement (I ended up removing it, it was a 
monstrosity of context hierarchies and WaitGroup hierarchies!). The 
pipeline pattern in Go somehow resembles it - and yet again, they are very 
different things.

Error handling should be explicit too. Currently it's not added; though I'm 
thinkering around it (channels or some function value?).

SimpleOneForOne is pretty much the same as OneForOne and you are right. 
However it needed some changes to provide facility for adding children 
dynamically. I think I'll be happy with just channels with these two cases 
(Error Handling and SimpleOneForOne), yet I like to wait a bit more and if 
got any, study the feedbacks.

Stuffing different concepts from different contexts, into other contexts, 
carelessly, might be harmful. Though the overall concept of supervisors in 
a simplified, explicit form still seems useful.

On Saturday, March 11, 2017 at 7:47:52 PM UTC+3:30, Jesper Louis Andersen 
wrote:
>
> If you try this in a real system, I'd be interested in how it fares.
>
> In Erlang, initialization in a supervision tree is synchronous with the 
> process initialization. That is, the supervisor doesn't continue with its 
> children stack unless the process successfully initialized. Making sure the 
> goroutine started up is often not enough. It is often the case what such a 
> child needs to register itself somewhere as an available child.
>
> Erlang systems usually build supervisor (worker) childs such that they can 
> be killed at any time, without the system becoming incorrect in its 
> internal state. One of the reasons this is possible is because in Erlang, 
> processes are truly isolated. Go, with a shared heap, needs to have 
> something like Context, so you can have the routine itself clean up. This 
> is supervision in Erlang is so ubiquitous: failure in a subsystem can be 
> cleaned up by the runtime automatically, and the supervision just 
> reestablishes the current  known invariant of the system. Faults of this 
> kind will usually fail a small number of processes, so the overall 
> reliability of the system is still in the higher nines (4-5 nines, or 
> more), depending on how you count in your SLA. In short, Erlang can cope 
> with an arbitrary panic() in a worker in ways that Go cannot.
>
> Because Go is a different language, the supervision strategy may or may 
> not work. And this is why I'm interested in hearing about where there are 
> trouble, and how you can work around that trouble. To me, the Context 
> package in the stdlib is an indicator for Go maturity. This is one of the 
> things needed for correct fault tolerant operation.
>
> Note that simple_one_for_one is a strategy which essentially optimizes a 
> one_for_one supervisor for a special case. In a one_for_one supervisor, you 
> have a static set of children, which is not going to change over the 
> operation of the application. Hence, each child is named with a 
> static-name, for registration purposes and for traceability purposes. The 
> problem you then have is how you want to handle a large dynamic set of 
> workers where workers gets added and removed quite often. The 
> simple_one_for_one supervisor exists to facilitate this particular 
> situation: it allows a large set of processes, all running the same code. 
> You can now tie the dynamic set of processes into your supervision tree, 
> and thus you can make sure to stop them again, should that part of the tree 
> become unstable. A common Erlang mistake is to have "naked" processes, 
> which are not linked into the tree. This is akin to having a goroutine 
> which is not linked to a Context: there is no way to remove that goroutine 
> unless it removes itself. It leads to leaks, either of processes, or of 
> goroutines. Chances are it is a less useful construction in Go.
>
> The rest_for_one strategy is the rarest one to be used. But it is hard to 
> implement with the other constructions, so it seems to be needed.
>
>
> On Sat, Mar 11, 2017 at 2:32 PM dc0d <kaveh.sh...@gmail.com <javascript:>> 
> wrote:
>
>> Yes, this one is using context.Context.
>>
>>
>> On Saturday, March 11, 2017 at 3:00:38 PM UTC+3:30, Jakob Borg wrote:
>>
>>> Interesting. I'm a fan of http://github.com/thejerf/suture/ which has a 
>>> similar goal but different implementation (and predates Context). 
>>>
>>> //jb
>>>
>>> On 11 Mar 2017, at 09:19, dc0d <kaveh.sh...@gmail.com> wrote:
>>>
>>> It just started as playing around recursive types in Go and ended up 
>>> writing this <https://github.com/dc0d/supervisor>. Though I could not 
>>> find a clean way ti implement rest_for_one strategy and error handling and 
>>> simple_one_for_one is in TODO list; any feedback would be appreciated!
>>>
>>> (https://github.com/dc0d/supervisor)
>>>
>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "golang-nuts" group.
>>>
>>> To unsubscribe from this group and stop receiving emails from it, send 
>>> an email to golang-nuts...@googlegroups.com.
>>>
>>>
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to