fix(secrets): consume Secrets 0.2.2 - clustered-secrets DI deadlock fixed upstream
Bumps the four ZB.MOM.WW.Secrets pins 0.2.1 -> 0.2.2 (closes the OtOpcUa side of scadaproj#1, tracked here as #482). 0.2.1's Akka replicator deadlocked any hosted process at startup when Secrets:Replication:Enabled was true: the package's DI graph closed a circular singleton dependency through factory lambdas (store decorator -> replicator -> actor provider -> cache invalidator -> resolver -> store), which MS.DI's StackGuard turns into a silent cross-thread call-site-lock deadlock. 0.2.2 defers the invalidator edge to first eviction. The flag stays default-false; enabling remains a per-environment decision. The_startup_hook_actually_creates_the_replication_actor is now a real test: SecretReplicationStarter's docs had promised it since the adoption, and the upstream fix finally makes a provider-based resolve runnable - container built exactly as the host does, hook started under a watchdog, replication actor proven to exist by ActorSelection on a self-joined single-node cluster (no TestKit needed, which matters because Akka.TestKit.Xunit2 is xunit-v2-only and this project is on xunit.v3). Also corrects the stale rationale that blamed the old hang on DistributedPubSub needing a joined cluster - the actor constructor was never reached; it was the DI cycle. Verified: SecretsReplicationRegistrationTests 8/8 on the 0.2.2 feed packages; full slnx build 0 errors; the 2-node Akka live convergence gate re-run against the published 0.2.2 packages passes 6/6 (write->peer, tombstone propagation without resurrection, delete visibility through the resolver cache, reverse direction, wrong-KEK fail-closed). Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
This commit is contained in:
@@ -24,15 +24,15 @@ namespace ZB.MOM.WW.OtOpcUa.Host.Configuration;
|
||||
/// unconditional.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <b>Known ineffective against ZB.MOM.WW.Secrets.Replicator.AkkaDotNet 0.2.0.</b> That
|
||||
/// version never binds its own <c>ISecretReplicator</c>:
|
||||
/// <c>AddZbSecretsAkkaReplication</c> calls <c>AddZbSecrets</c> first, which
|
||||
/// <c>TryAdd</c>s <c>NoOpSecretReplicator</c>, making the package's own subsequent
|
||||
/// <c>TryAddSingleton<ISecretReplicator></c> a no-op. Resolving the store therefore
|
||||
/// builds a <c>ReplicatingSecretStore</c> around a no-op replicator and spawns no actor.
|
||||
/// This hook is correct and stays in place for when the library is fixed, but replication
|
||||
/// must be treated as <b>non-functional</b> until then — see the skipped test
|
||||
/// <c>SecretsReplicationRegistrationTests.The_startup_hook_actually_creates_the_replication_actor</c>.
|
||||
/// <b>History — this hook has met two library defects, both fixed.</b> Against 0.2.0 it was
|
||||
/// inert: the package never bound its own <c>ISecretReplicator</c> (TryAdd registration
|
||||
/// order), so this resolve built a <c>ReplicatingSecretStore</c> around a no-op sink and
|
||||
/// spawned no actor. Against 0.2.1 it was worse: the resolve <b>deadlocked the host at
|
||||
/// startup</b> — the package's DI graph had a circular singleton dependency, invisible to
|
||||
/// the container through factory lambdas (scadaproj#1). Fixed in 0.2.2 by deferring the
|
||||
/// cycle-closing invalidator edge;
|
||||
/// <c>SecretsReplicationRegistrationTests.The_startup_hook_actually_creates_the_replication_actor</c>
|
||||
/// exercises this hook against a built provider on a real single-node cluster.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="services">Root provider used to resolve the (decorated) secret store exactly once.</param>
|
||||
|
||||
Reference in New Issue
Block a user