TL;DR: Try to keep your start up encoded as much as possible with the standard facilities of sub-supervisors, children (the order of them) as well as the restart strategy and you’ll guarantee that your system looks like any other. If
ConCache is actually doing logic, don’t make it a supervisor. Catastrophic failure should be encoded in the
init to prevent the system/supervisor and the rest of the children from starting.
A bit of meditation on the things in this post, written by the great Fred Hebert: It’s About the Guarantees
I think maybe more information about everything is in order.
Ordinarily, a supervisor wouldn’t be a process that actually does logic, so I’m weary of this being started and called
:cache in your supervision tree.
What is it that can fail when starting the supervisor and why do we need to start all our children before
post_start? Usually when we require a specific ordering of started processes we can simply put them before/after other processes in the children list. A good model is to have processes that are tied to each other in functionality start under the same supervisor with their relationship encoded in the
restart strategy. This might not be needed here, but it’s worth looking at in the future when your supervision tree grows.
Encoding catastrophic failure into your startup is best done by setting up whatever requirements you have in a process’
init (that would be the
ConCache.init call here). If there is something that simply will not allow for your application to start without, put it there and the BEAM will make sure your app just doesn’t start if this condition isn’t met.
If a process is needed for
ConCache to be running, put its startup before
ConCache and that will have to start up properly for
ConCache to be started. Conversely, if
ConCache needs to be running for something else to function, putting it before it in the children list will ensure that it needs to start properly for the other thing to start. This requires you to bail out if things aren’t actually working as they should, so detection of that property is needed in the
init of the process.
This applies to all processes, so it’s good to think of your startup process as potentially containing information about what’s important. If something is pivotal to the whole system and it simply can’t run without it, put that first in your children list, though you’ll have to have the dependencies it has start before it, obviously.
With regards to general cache behavior, I favor the idea of checking a cache for data and if it doesn’t have it, populate the cache with that data.
Edit: If you need to pre-populate the cache you have to make the choice whether or not to make that hold up your startup (if the cache is important enough) or delay that by, for example, sending yourself a message in the
init callback in order to load the cache data in a
handle_info. Both behaviors will likely die on error, so if the cache is important enough you very likely want it to die on
init instead of later.