1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//! `TemplateCache` - issue #13's live `bounded_context ->
//! dispatch_template` lookup, and ultra-review bug_001/bug_005's own
//! fix for it. Every `Registered*` dispatch map `skilj`'s facade holds
//! (`command_types`/`event_types`/`projections`/`snapshots`) is keyed
//! by whatever literal name `.bounded_context(name)`/`#[auto_register]`
//! declared at `.build()` time - for a templated tenant, that's always
//! the *template*'s own name, never the tenant's (a tenant's name is
//! chosen at runtime, long after `.build()` ran, so it can never be a
//! map key). `TemplateCache` is what lets a dispatcher resolve a
//! tenant's own runtime-chosen name to its template's before the real
//! lookup, making an already-compiled `decide()`/`project()`/etc.
//! reachable for every tenant with no redeploy.
//!
//! Lives here, not in the `skilj` facade crate where it first did,
//! because `skilj-graphql`'s resolvers need to refresh it too (see
//! below) - `skilj-graphql` cannot depend on `skilj` (the dependency
//! runs the other way), so the shared type has to live somewhere both
//! already depend on. `#[derive(Clone)]` over `Arc`-wrapped internals,
//! the same "hand out a cheap clone" shape `EventCache` already uses.
//!
//! Reads `bounded_contexts.dispatch_template`
//! (`db::list_dispatch_template_mappings`), not `bounded_contexts.
//! template` - a deliberate second, permanent field. `template` is
//! correctly cleared by `DeleteBoundedContext`'s `ON DELETE SET NULL`
//! cascade (that's the right behaviour for *that* field: a tenant whose
//! template was deleted has nothing left to display or resync from).
//! `dispatch_template` is set once, at tenant creation, and never
//! cleared by anything - deleting the template a tenant was stamped
//! from must not also silently stop that tenant from processing
//! commands, which is exactly what reading the nullable `template`
//! column here used to do (ultra-review bug_005).
//!
//! Refreshed two ways: once at `SkiljBuilder::build()` startup, and
//! synchronously by `createBoundedContextFromTemplate`'s own resolver
//! right after it commits a new tenant - closing the same-instance race
//! ultra-review bug_001 found (the cross-instance `RegistrationChanged`
//! NOTIFY listener refreshes every *other* instance, but was the only
//! refresh path at all, so an immediate `submitCommand` on the same
//! instance that just created the tenant could lose the race and see a
//! spurious `no_decider_registered`).
use cratePool;
use HashMap;
use ;
/// See this module's own doc comment.