<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
Message: 17<br>
Date: Thu, 21 May 2015 16:32:40 -0400<br>
From: Fred Hebert <<a href="mailto:mononcqc@ferd.ca">mononcqc@ferd.ca</a>><br>
To: Roger Lipscombe <<a href="mailto:roger@differentpla.net">roger@differentpla.net</a>><br>
Cc: "<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a>" <<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a>><br>
Subject: Re: [erlang-questions] Why have a supervisor behaviour?<br>
Message-ID: <20150521203238.GA52846@ferdair.local><br>
Content-Type: text/plain; charset=us-ascii; format=flowed<br>
<br>
On 05/21, Roger Lipscombe wrote:<br>
>I need delayed _restart_. Is this what Jesper refers to when he talks<br>
>about "a delay_manager"? Such that init queries that and then<br>
>might/might not delay?<br>
<br>
That's a classic question, and one I started answering differently.<br>
Requiring a timeout in your supervisor rebooting function means that you<br>
are letting things crash or restart for the wrong reason.<br>
<br>
The thing is, it's all about the guarantees[1]. In a nutshell, a<br>
supervisor should exit on any error, and ideally bring you back to a<br>
known, stable state.<br>
<br>
So of course all expected or unexpected errors should be able to bring<br>
you back to that state properly, specifically transient errors.<br>
<br>
But the distinction is that because supervisors boot synchronously for<br>
all apps, they also represent a chain of dependencies of what should be<br>
available to all processes started *after* them.<br>
<br>
That's why failure modes such as 'one for all' or 'rest for one' exist.<br>
They allow you to specify that the processes there are related to each<br>
other in ways that their death violates some guarantee of invariant in<br>
the system and that the only good way to restart is by refreshing all of<br>
them.<br>
<br>
In a nutshell, if you expect disconnections or event that require a<br>
backoff to happen frequently enough they are to be expected by the<br>
processes depending on yours, then that connection or that event is not<br>
a thing that should take place in your process' init function. Otherwise<br>
you're indirectly stating that without this thing working, the system<br>
should just not boot.<br>
<br>
See the example in [2] for an idea of how to respect this. This does not<br>
change the code in any major way, but moves function calls around to<br>
properly respect these semantics.<br>
<br>
My position is that this isn't a problem with supervisors' interface,<br>
but in how they are being use and what they mean for your system. I know<br>
this is not the most helpful response, but oh well.<br>
<br>
<br>
[1]: <a href="http://ferd.ca/it-s-about-the-guarantees.html" target="_blank">http://ferd.ca/it-s-about-the-guarantees.html</a><br>
[2]: <a href="http://www.erlang-in-anger.com" target="_blank">http://www.erlang-in-anger.com</a>, section 2.2.3<br>
<br><br></blockquote><div>I wanted to add, every time I've seen this pattern brought up (a supervisor with a delayed restart), it's been due to something on the network has become unavailable, or overloaded to where it can't respond in a reasonable amount of time, that sort of thing, and the developers involved were seeing restart limits being hit and the system coming down, even though there was every reason to expect the resource to become available again, in time.<br><br>If that's the case for you, those types of issues would likely be better addressed using a circuit breaker or similar[1] than a custom supervisor, for the reasons Fred mentions. <br><br>In general, having this thing be unavailable is either due to bad internal state (in which case a supervisor can help you), or something external to your program (in which case the supervisor can't), and in the latter case you should be thinking about how the system should behave when it's unavailable (since it would be unavailable even with a delayed supervisor in any case). Making it a clean response that means "this resource is not available" allows you to address it in a well defined way, rather than having a child process that may or may not be there being called from elsewhere in your system. <br><br>[1]: <a href="https://github.com/jlouis/fuse">https://github.com/jlouis/fuse</a></div></div><br></div></div>