Encryptor.Vault.Supervisor (Encryptor v0.2.0)

Copy Markdown View Source

The supervisor a vault starts, and the only place a vault has processes.

The engine is data, not a service: keyrings, CMMs and clients are structs, and encrypt and decrypt are pure functions over them. Exactly one component in the whole library owns a process, the materials cache, so this supervisor is deliberately small and its child list is deliberately short (ADR-0001 decision 2).

The children, in order

  1. Encryptor.Vault.Lifecycle - owns the frozen configuration's lifetime. It is first so that the configuration is published before anything that might read it starts.
  2. The materials cache, when :cache is configured. Registered under Encryptor.Vault.cache_name/1, so two vaults never share one.
  3. Encryptor.Vault.CacheRecycler, when - and only when - there is a cache. It stops the cache child on the configured :recycle_after interval and starts it again, which is the only bound the engine permits on a cache that has no capacity limit, no sweeper, and no way for outside code to measure it (ADR-0001 decision 6). It is not a refinement of the cache and it may not be simplified away.
  4. The key provider, when its module exports child_spec/1. Its child id is set to the provider module here, which is what lets Encryptor.Vault.ensure_provider_started/2 ask this supervisor whether the provider is alive without knowing anything about how the provider registered itself.

A vault configured with cache: false still starts, with the cache child simply absent: a provider may need supervision even when the cache does not exist.

Configuration resolves here, once

start_link/2 runs the five-layer precedence chain and every start-time check Encryptor.Vault.Config owns, before the supervisor process exists. A configuration the vault refuses is an ordinary {:error, %Encryptor.Error{}} from start_link/2 rather than a running vault that fails at its first encrypt - and rather than a supervisor that starts and immediately dies, which would report a design decision as a crash. It re-runs on a restart, so a vault brought back up reads its configuration again.

The strategy is :one_for_one, so a recycled cache does not take the provider or the frozen configuration down with it.

Summary

Functions

Returns a specification to start this module under a supervisor.

Resolves a vault's configuration, then starts its supervisor registered under Encryptor.Vault.supervisor_name/1.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

start_link(vault, start_opts \\ [])

@spec start_link(
  module(),
  keyword()
) :: Supervisor.on_start()

Resolves a vault's configuration, then starts its supervisor registered under Encryptor.Vault.supervisor_name/1.

start_opts are layer 4 of the configuration precedence chain.