The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.
Follows the import procedure in README.md.
source/ the originating repository verbatim — 78 documents, 28 SVGs,
8 manifests, plus .source-revision recording the commit
final/ the SSOT
document.md 729 lines written from the 29 experiment documents, not
concatenated: what was predicted, what was measured, and
where the measurement itself was wrong
evidence/raw 125 outputs, flattened to <experiment>__<file> because
the originals collided (01-baseline.txt appeared three
times) and the audit only globs the top level
evidence/meta one per raw file; command and exitCode are null and the
README says why rather than inventing them
evidence/browser 22 captures
assets/ three diagrams through techviz
.techviz/ their VizSpecs
A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.
Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.
verify-pipeline.py passes. audit-records.py reports no issues.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
81 lines
5.1 KiB
Plaintext
81 lines
5.1 KiB
Plaintext
# revision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
|
|
|
## A. public types: files referencing them outside the owning leaf
|
|
MessagingTransport 12
|
|
MessagingRuntime 3
|
|
MessagingRuntimeRegistry 3
|
|
MessagingRuntimeLease 2
|
|
DefaultMessagingRuntimeRegistry 2
|
|
GracefulShutdownCoordinator 11
|
|
MessagingLifecycle 0
|
|
TransportDelivery 9
|
|
TransportSettlement 4
|
|
TransportPublishRequest 18
|
|
TransportPublishResult 10
|
|
TransportConsumerSpec 14
|
|
TransportConsumerRegistration 8
|
|
|
|
## B. MessagingLifecycle: every occurrence in the repository
|
|
src/messaging/messaging-transport-spi/src/main/java/dev/caskeleton/messaging/transport/MessagingLifecycle.java:17:public interface MessagingLifecycle {
|
|
src/messaging/messaging-transport-spi/src/test/java/dev/caskeleton/messaging/transport/MessagingLifecycleTest.java:5:import dev.caskeleton.messaging.transport.MessagingLifecycle.ShutdownPhase;
|
|
src/messaging/messaging-transport-spi/src/test/java/dev/caskeleton/messaging/transport/MessagingLifecycleTest.java:57: assertThat(MessagingLifecycle.DEFAULT_DRAIN_DEADLINE).isEqualTo(Duration.ofSeconds(30));
|
|
--- anything implementing it?
|
|
exit=1 (1 = nothing implements it)
|
|
--- anything referencing ShutdownPhase outside the leaf?
|
|
exit=1 (1 = no external consumer)
|
|
|
|
## C. what the ordering tests actually assert
|
|
@Test
|
|
void publishAdmissionClosesBeforeConsumersArePaused() {
|
|
List<ShutdownPhase> order = List.of(ShutdownPhase.values());
|
|
|
|
assertThat(order.indexOf(ShutdownPhase.STOP_PUBLISH_ADMISSION))
|
|
.isLessThan(order.indexOf(ShutdownPhase.PAUSE_CONSUMERS));
|
|
}
|
|
|
|
@Test
|
|
void handlersDrainBeforeTheirSettlementsAreFlushed() {
|
|
List<ShutdownPhase> order = List.of(ShutdownPhase.values());
|
|
|
|
assertThat(order.indexOf(ShutdownPhase.DRAIN_HANDLERS))
|
|
.as("flushing before the handlers finish would lose the settlements they produce")
|
|
.isLessThan(order.indexOf(ShutdownPhase.FLUSH_SETTLEMENTS));
|
|
}
|
|
|
|
## D. the shutdown path that IS wired
|
|
--- who implements MessagingTransport (the SPI that is used)
|
|
src/messaging/messaging-kafka/src/main/java/dev/caskeleton/messaging/kafka/KafkaMessagingTransport.java:41:public final class KafkaMessagingTransport implements MessagingTransport {
|
|
src/messaging/messaging-nats-experimental/src/main/java/dev/caskeleton/messaging/nats/NatsJetStreamTransport.java:54:public final class NatsJetStreamTransport implements MessagingTransport {
|
|
src/messaging/messaging-pulsar-experimental/src/main/java/dev/caskeleton/messaging/pulsar/PulsarMessagingTransport.java:47:public final class PulsarMessagingTransport implements MessagingTransport {
|
|
src/messaging/messaging-rabbit/src/main/java/dev/caskeleton/messaging/rabbit/RabbitMessagingTransport.java:39:public final class RabbitMessagingTransport implements MessagingTransport {
|
|
src/messaging/messaging-runtime-core/src/test/java/dev/caskeleton/messaging/runtime/DefaultMessagePublisherTest.java:426: private static final class RecordingTransport implements MessagingTransport {
|
|
src/messaging/messaging-transport-spi/src/test/java/dev/caskeleton/messaging/transport/MessagingRuntimeRegistryTest.java:230:final class FakeTransport implements MessagingTransport {
|
|
--- the wired shutdown bean and what it performs
|
|
30:public final class MessagingShutdownLifecycle implements SmartLifecycle {
|
|
88: admission.stopAcceptingNewWork();
|
|
90: drain.beginDrain(startedAt);
|
|
92: while (!drain.isDrained(clock.get()) && clock.get().isBefore(deadline)) {
|
|
121: public int getPhase() {
|
|
--- GracefulShutdownCoordinator consumers
|
|
src/messaging/messaging-kafka/src/main/java/dev/caskeleton/messaging/kafka/KafkaConsumerRegistrar.java
|
|
src/messaging/messaging-kafka/src/test/java/dev/caskeleton/messaging/kafka/KafkaBrokerCertificationIT.java
|
|
src/messaging/messaging-kafka/src/test/java/dev/caskeleton/messaging/kafka/KafkaBrokerIT.java
|
|
src/messaging/messaging-kafka/src/test/java/dev/caskeleton/messaging/kafka/KafkaConsumerRegistrarTest.java
|
|
src/messaging/messaging-kafka/src/test/java/dev/caskeleton/messaging/kafka/KafkaConsumerSettlementIT.java
|
|
src/messaging/messaging-rabbit/src/main/java/dev/caskeleton/messaging/rabbit/RabbitConsumerRegistrar.java
|
|
src/messaging/messaging-rabbit/src/test/java/dev/caskeleton/messaging/rabbit/RabbitRuntimeTest.java
|
|
src/messaging/messaging-spring-boot-starter/src/main/java/dev/caskeleton/messaging/autoconfigure/MessagingCoreAutoConfiguration.java
|
|
src/messaging/messaging-spring-boot-starter/src/main/java/dev/caskeleton/messaging/autoconfigure/MessagingShutdownLifecycle.java
|
|
src/messaging/messaging-spring-boot-starter/src/test/java/dev/caskeleton/messaging/autoconfigure/MessagingAutoConfigurationTest.java
|
|
src/messaging/messaging-spring-boot-starter/src/test/java/dev/caskeleton/messaging/autoconfigure/MessagingShutdownLifecycleTest.java
|
|
|
|
## E. the eight declared phases vs what the wired path performs
|
|
22: STOP_PUBLISH_ADMISSION,
|
|
24: STOP_NEW_HANDLERS,
|
|
26: PAUSE_CONSUMERS,
|
|
28: DRAIN_HANDLERS,
|
|
30: FLUSH_SETTLEMENTS,
|
|
32: AWAIT_PRODUCER_CONFIRMS,
|
|
34: RELEASE_OUTBOX_LEASES,
|
|
36: CLOSE_CONNECTIONS
|