Skip to content

Commit c989f1b

Browse files
committed
more analyze
1 parent 258503e commit c989f1b

File tree

2 files changed

+23
-22
lines changed

2 files changed

+23
-22
lines changed

specs/002-session-state-machine/spec.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,27 +67,27 @@ As a developer building a distributed application on top of Raft with the client
6767

6868
### Acceptance Scenarios
6969

70-
1. **Given** a developer has defined a simple user state machine (e.g., a counter), **When** a client submits a command with a new session ID and request ID, **Then** the client-server layer detects it's not a duplicate, forwards it to the user state machine, processes the command, caches the response, and returns the result to the client.
70+
1. **Given** a developer has extended SessionStateMachine with their business logic, **When** a client submits a command with a new session ID and request ID, **Then** the base class template method detects it's not a duplicate, narrows state to UserSchema, calls the user's applyCommand method, merges changes, caches the response, and returns the result to the client.
7171

72-
2. **Given** a client submits the same command twice (same session ID and request ID), **When** the second request arrives, **Then** the client-server layer detects the duplicate, retrieves the cached response, and returns it without invoking the user state machine again.
72+
2. **Given** a client submits the same command twice (same session ID and request ID), **When** the second request arrives, **Then** the base class template method detects the duplicate, retrieves the cached response, and returns it without calling the user's applyCommand method again.
7373

74-
3. **Given** a developer has defined a user state machine, **When** they wire it into their application by routing RaftAction events from the client-server library to the state machine and sending state machine responses back via ServerAction events, **Then** all commands flow through idempotency checking automatically.
74+
3. **Given** a developer has extended SessionStateMachine, **When** they wire it into their application by converting RaftAction events from the client-server library to SessionCommand and applying to the state machine, and sending state machine responses back via ServerAction events, **Then** all commands flow through the base class template method's idempotency checking automatically.
7575

76-
4. **Given** a user state machine processes a command and returns an error, **When** the client retries with the same request ID, **Then** the cached error response is returned without reprocessing the command.
76+
4. **Given** a user's applyCommand method processes a command and returns an error, **When** the client retries with the same request ID, **Then** the base class template method returns the cached error response without calling applyCommand again.
7777

78-
5. **Given** multiple clients submit different commands in parallel, **When** Raft applies these commands in consensus order, **Then** each command goes through idempotency checking and is processed exactly once by the user state machine.
78+
5. **Given** multiple clients submit different commands in parallel, **When** Raft applies these commands in consensus order, **Then** each command goes through the template method's idempotency checking and is processed exactly once by the user's applyCommand method.
7979

80-
6. **Given** a user state machine generates server-initiated requests during command processing, **When** the state machine returns these requests, **Then** the user takes them and sends via ServerAction.SendServerRequest through the client-server library, and the session state machine tracks them as pending until acknowledged.
80+
6. **Given** a user's applyCommand method generates server-initiated requests during command processing, **When** the method returns these in the (response, List[SR]) tuple, **Then** the base class template method adds them to pending state and returns them, and the user sends them via ServerAction.SendServerRequest through the client-server library.
8181

82-
7. **Given** a user state machine needs to produce side effects (e.g., send a message to a client), **When** processing a command, **Then** the state machine returns both a response and a list of server-initiated requests, which the user must send through the client-server library.
82+
7. **Given** a user's applyCommand method needs to produce side effects (e.g., send a message to a client), **When** processing a command, **Then** the method returns both a response and a list of server-initiated requests (in the tuple), which the base class returns to the user who must send them through the client-server library.
8383

8484
8. **Given** a client receives a server-initiated request, **When** the client processes it, **Then** the client immediately sends an acknowledgment (ServerRequestAck) back to the server.
8585

86-
9. **Given** the server receives a ServerRequestAck for request ID N, **When** it is committed through Raft, **Then** the session state machine removes all pending server-initiated requests with ID ≤ N from its pending state (cumulative acknowledgment).
86+
9. **Given** the server receives a ServerRequestAck for request ID N, **When** it is committed through Raft, **Then** the base class template method removes all pending server-initiated requests with ID ≤ N from the session state (cumulative acknowledgment).
8787

8888
10. **Given** an external retry process needs to resend server-initiated requests, **When** it performs a dirty read of the state machine's unacknowledged list and applies retry policy locally, **Then** if the policy indicates requests need retry, it sends a GetRequestsForRetry command and the state machine atomically identifies requests, updates their lastSentAt, and returns the authoritative list. The process discards the dirty read data and uses only the command response. (Optimization: dirty read allows skipping command when nothing needs retry)
8989

90-
11. **Given** a Raft cluster performs a snapshot, **When** capturing state, **Then** both the user state machine state and the client-server session state (including response cache and pending server-initiated requests) are included in the snapshot.
90+
11. **Given** a Raft cluster performs a snapshot, **When** the user's takeSnapshot method is called, **Then** the user serializes the entire HMap[CombinedSchema[UserSchema]] which contains both session state (SessionSchema prefixes) and user business logic state (UserSchema prefixes), including response cache and pending server-initiated requests.
9191

9292
### Edge Cases
9393

@@ -123,11 +123,11 @@ As a developer building a distributed application on top of Raft with the client
123123
- **FR-015**: System MUST NOT impose size limits on cached responses (for now)
124124

125125
#### State Machine Interface (Library Provides)
126-
- **FR-016**: System MUST provide a state machine interface that accepts RaftAction events (ClientRequest, ServerRequestAck, SessionCreationConfirmed, SessionExpired) and returns state transitions
126+
- **FR-016**: System MUST provide a state machine interface that accepts SessionCommand commands (ClientRequest, ServerRequestAck, SessionCreationConfirmed, SessionExpired, GetRequestsForRetry) and returns state transitions. Note: Users convert RaftAction events from client-server library to SessionCommand at the integration layer.
127127
- **FR-017**: System MUST return responses that the user can send via ServerAction.SendResponse through the client-server library (library does NOT send responses directly)
128128
- **FR-018**: System MUST return server-initiated requests that the user can send via ServerAction.SendServerRequest through the client-server library (library does NOT send requests directly)
129-
- **FR-019**: System MUST process RaftAction.ClientRequest events by performing idempotency checking, invoking user state machine, caching responses, and returning the response
130-
- **FR-020**: System MUST process RaftAction.ServerRequestAck events to remove acknowledged server-initiated requests from the session state machine; when processing an acknowledgment for request ID N, the system MUST remove all pending requests with ID ≤ N (cumulative acknowledgment)
129+
- **FR-019**: System MUST process SessionCommand.ClientRequest by performing idempotency checking, calling user's applyCommand method, caching responses, and returning the response
130+
- **FR-020**: System MUST process SessionCommand.ServerRequestAck to remove acknowledged server-initiated requests from the session state; when processing an acknowledgment for request ID N, the system MUST remove all pending requests with ID ≤ N (cumulative acknowledgment)
131131
- **FR-021**: System MUST allow user state machines to generate server-initiated requests as part of command processing, which are added to pending state and returned for the user to send
132132

133133
#### Server-Initiated Request Management

specs/002-session-state-machine/tasks.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -320,12 +320,14 @@
320320
- [ ] **T042** Constitution compliance verification
321321
- **Checklist**: Review all constitution points from plan.md
322322
- **Verify**:
323-
- No unsafe operations
324-
- HMap provides type safety
325-
- No exceptions in business logic
326-
- Extends existing StateMachine trait
327-
- Pure functions only
328-
- No serialization library dependency
323+
- No unsafe operations (Principle I)
324+
- HMap provides type safety (Principle I)
325+
- No exceptions in business logic (Principle II)
326+
- Extends existing StateMachine trait (Principle III)
327+
- Pure functions only (Principle I)
328+
- No serialization library dependency (clean architecture)
329+
- **ZIO Clock service used for all time operations** - verify Instant values come from ZIO Clock, not Instant.now() or System.currentTimeMillis() (Principle IV)
330+
- **No java.util.Random or UUID.randomUUID()** - only ZIO Random service if needed (Principle IV)
329331
- **Success**: All constitutional requirements met
330332

331333
- [ ] **T043** Code review and cleanup
@@ -387,6 +389,7 @@ Different files, no dependencies:
387389

388390
### Phase 3.3 - Contract Tests (All Parallel)
389391
```bash
392+
# T012-T017 can run simultaneously
390393
sbt "testOnly *SessionStateMachineTemplateSpec"
391394
sbt "testOnly *IdempotencySpec"
392395
sbt "testOnly *ResponseCachingSpec"
@@ -396,10 +399,8 @@ sbt "testOnly *InvariantSpec"
396399
```
397400

398401
### Phase 3.5 - Documentation (All Parallel)
399-
- T039: SessionStateMachine scaladoc
400-
- T040: Core types scaladoc
401-
- T041: Module README
402-
- T042: Migration guide
402+
- T037-T041: Documentation tasks can run in parallel
403+
- T042-T043: Constitution compliance and code review
403404

404405
---
405406

0 commit comments

Comments
 (0)