pub struct Assembly {
pub database: Arc<Database>,
pub jobs: JobQueue,
pub metrics: Arc<Metrics>,
pub notifiers: Notifiers,
/* private fields */
}Expand description
What survives a configuration reload.
Every generation rebuilds its profiles, its routers, its job registry, its egress clients and any signer backend whose configuration moved. The things here are built once for the life of the process and handed to each generation instead — and after three rounds of moving things off this list, everything left is here because rebuilding it would lose something, never because rebuilding it would merely cost something:
databaseandjobsare the pool and its enqueue side.database.urlis the one keycrate::reloadstill refuses, and this is why.metricsis a correctness requirement. A registry rebuilt per generation would reset every counter onSIGHUP, and a counter going backwards is precisely how Prometheus recognises a process restart — sorate()would report the whole pre-reload total as a spike on every configuration change.signersis the previous generation’s backend set, kept so the next reload can reuse a backend whose configuration did not move (seesigner::build_backends);infosthe same for their read sides. Behind aMutexbecause each is written once per generation; nothing reads either to serve a request, since aProfileholds its own read side.rolesdecides whether there are backends at all: only a process running theworkerrole builds one, so the others never read a CA key, log in to a token or contact a relay’s upstream — not at startup, not on reload.notifiersis a handle rather than a map, so[notify]can reload underneath the backends that captured it.
resolver and proxies used to be here, justified by the signers caching
them at construction. They moved to Egress when that stopped being a
reason to freeze [dns]/[proxy] and became a reason to rebuild a signer.
Fields§
§database: Arc<Database>§jobs: JobQueue§metrics: Arc<Metrics>§notifiers: NotifiersImplementations§
Source§impl Assembly
impl Assembly
Sourcepub fn new(
roles: RoleSet,
resolved: &[ProfileConfig],
database: Arc<Database>,
jobs: JobQueue,
config: &Config,
) -> Result<(Self, GenerationParts)>
pub fn new( roles: RoleSet, resolved: &[ProfileConfig], database: Arc<Database>, jobs: JobQueue, config: &Config, ) -> Result<(Self, GenerationParts)>
Builds everything that outlives a generation, plus the first generation’s own parts.
Those come back rather than being kept here because they are not
long-lived: the caller hands them to
profile::build_all_with and then
forgets them, and every later generation builds its own through
build_parts.
Sourcepub fn build_parts(
&self,
resolved: &[ProfileConfig],
config: &Config,
) -> Result<GenerationParts>
pub fn build_parts( &self, resolved: &[ProfileConfig], config: &Config, ) -> Result<GenerationParts>
Builds one generation’s egress, dispatchers and signer backends, without publishing any of them.
Separate from publish_notifiers and
publish_signers because a reload must be able
to fail after building all three and still leave the running generation
untouched. Everything fallible is here; everything published is there.
May block: RelaySigner::from_config contacts the upstream the first
time it is built for an account with no kid sidecar yet, which is why
server::supervisor::supervise_reloads runs this on a blocking thread.
Sourcepub fn publish_notifiers(&self, dispatchers: DispatcherMap)
pub fn publish_notifiers(&self, dispatchers: DispatcherMap)
Makes dispatchers the generation every long-lived reader sees.
Synchronous, and deliberately: it is one of the sends a reload makes back-to-back so no task can observe a half-swapped generation.
Sourcepub fn publish_signers(
&self,
signers: SignerSet,
infos: SignerSet<dyn SignerInfo>,
)
pub fn publish_signers( &self, signers: SignerSet, infos: SignerSet<dyn SignerInfo>, )
Records signers as what the next reload compares against, and drops
whatever the generation before it held.
That drop is the point at which a backend nobody references any more —
an unmounted profile’s, or the instance a [signer] edit replaced — is
finally released. Deliberately after its replacement was built and has
adopted its state, never before.
Auto Trait Implementations§
impl !Freeze for Assembly
impl !RefUnwindSafe for Assembly
impl !UnwindSafe for Assembly
impl Send for Assembly
impl Sync for Assembly
impl Unpin for Assembly
impl UnsafeUnpin for Assembly
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more