src/coordinator/CoordinatorPolicy.bend
mylsm-lsm-store@0.6.0.0 · 133 lines · 0 definitions
1import Base
2
3# Represents the owner lifecycle around lock, recovery, endpoint, and shutdown.
4type State is Data:
5 Starting{}
6 Locked{}
7 Recovered{}
8 Serving{}
9 Stopping{}
10 EndpointRemoved{}
11 Closed{}
12 Failed{}
13
14# Represents one external result or requested lifecycle action.
15type OwnerEvent is Data:
16 AcquireLock{}
17 RecoveryComplete{}
18 PublishEndpoint{}
19 BeginShutdown{}
20 RemoveEndpoint{}
21 ReleaseLock{}
22 Failure{}
23
24# Returns the next legal state or rejects an out-of-order event.
25type Decision is Data:
26 Advance{state: State}
27 Reject{}
28
29# Classifies durable failures before mapping them into wire statuses.
30type FailureKind is Data:
31 BusyFailure{}
32 TimeoutFailure{}
33 NotFoundFailure{}
34 InvalidArgumentFailure{}
35 AlreadyExistsFailure{}
36 UnsupportedPlatformFailure{}
37 ResourceLimitFailure{}
38 CorruptionFailure{}
39 IoFailure{}
40 CommitUnknownFailure{}
41
42# Defines the typed response statuses available to coordinator clients.
43type ReplyStatus is Data:
44 SuccessStatus{}
45 InvalidArgumentStatus{}
46 AlreadyExistsStatus{}
47 UnsupportedPlatformStatus{}
48 NotFoundStatus{}
49 BusyStatus{}
50 TimeoutStatus{}
51 ResourceLimitStatus{}
52 CorruptionStatus{}
53 IoStatus{}
54 CommitUnknownStatus{}
55
56# Records whether the open path acquired, contended on, or failed to acquire the lock.
57type LockOutcome is Data:
58 LockAcquired{}
59 LockBusy{}
60 LockFailed{}
61
62# Records whether canonical endpoint inspection found a live candidate.
63type EndpointOutcome is Data:
64 EndpointPresent{}
65 EndpointMissing{}
66 EndpointFailed{}
67
68# Selects local ownership, remote use, or a typed open failure.
69type OpenRole is Data:
70 LocalOwner{}
71 ExistingOwnerClient{}
72 ReturnBusy{}
73 PropagateOpenFailure{}
74
75# Chooses local ownership or an established endpoint from lock observations.
76def open.role(lock: LockOutcome, endpoint: EndpointOutcome) -> OpenRole:
77 match lock:
78 case LockAcquired{}: LocalOwner{}
79 case LockBusy{}:
80 match endpoint:
81 case EndpointPresent{}: ExistingOwnerClient{}
82 case EndpointMissing{}: ReturnBusy{}
83 case EndpointFailed{}: PropagateOpenFailure{}
84 case LockFailed{}: PropagateOpenFailure{}
85
86def failure.status(kind: FailureKind) -> ReplyStatus:
87 match kind:
88 case BusyFailure{}: BusyStatus{}
89 case TimeoutFailure{}: TimeoutStatus{}
90 case NotFoundFailure{}: NotFoundStatus{}
91 case InvalidArgumentFailure{}: InvalidArgumentStatus{}
92 case AlreadyExistsFailure{}: AlreadyExistsStatus{}
93 case UnsupportedPlatformFailure{}: UnsupportedPlatformStatus{}
94 case ResourceLimitFailure{}: ResourceLimitStatus{}
95 case CorruptionFailure{}: CorruptionStatus{}
96 case IoFailure{}: IoStatus{}
97 case CommitUnknownFailure{}: CommitUnknownStatus{}
98
99# Applies one lifecycle event without performing host effects.
100def step(state: State, event: OwnerEvent) -> Decision:
101 match state:
102 case Starting{}:
103 match event:
104 case AcquireLock{}: Advance{Locked{}}
105 case Failure{}: Advance{Failed{}}
106 case _: Reject{}
107 case Locked{}:
108 match event:
109 case RecoveryComplete{}: Advance{Recovered{}}
110 case Failure{}: Advance{Failed{}}
111 case _: Reject{}
112 case Recovered{}:
113 match event:
114 case PublishEndpoint{}: Advance{Serving{}}
115 case Failure{}: Advance{Failed{}}
116 case _: Reject{}
117 case Serving{}:
118 match event:
119 case BeginShutdown{}: Advance{Stopping{}}
120 case Failure{}: Advance{Failed{}}
121 case _: Reject{}
122 case Stopping{}:
123 match event:
124 case RemoveEndpoint{}: Advance{EndpointRemoved{}}
125 case Failure{}: Advance{Failed{}}
126 case _: Reject{}
127 case EndpointRemoved{}:
128 match event:
129 case ReleaseLock{}: Advance{Closed{}}
130 case Failure{}: Advance{Failed{}}
131 case _: Reject{}
132 case Closed{}: Reject{}
133 case Failed{}: Reject{}