/ src / lightspeed / agent / typestate.gleam
typestate.gleam
 1  //// Typestate lifecycle for Lightspeed session agents.
 2  
 3  /// Marker type for a disconnected agent.
 4  pub type Disconnected {
 5    Disconnected
 6  }
 7  
 8  /// Marker type for an agent performing protocol handshake.
 9  pub type Handshaking {
10    Handshaking
11  }
12  
13  /// Marker type for an agent whose component has mounted.
14  pub type Mounted {
15    Mounted
16  }
17  
18  /// Marker type for an active live agent.
19  pub type Live {
20    Live
21  }
22  
23  /// Marker type for an agent draining before shutdown.
24  pub type Draining {
25    Draining
26  }
27  
28  /// Marker type for a terminated agent.
29  pub type Terminated {
30    Terminated
31  }
32  
33  /// Lifecycle labels useful for logs and protocol diagnostics.
34  pub type Lifecycle {
35    DisconnectedLabel
36    HandshakingLabel
37    MountedLabel
38    LiveLabel
39    DrainingLabel
40    TerminatedLabel
41  }
42  
43  /// A session agent parameterized by lifecycle state.
44  pub opaque type Agent(state) {
45    Agent(id: String, label: Lifecycle)
46  }
47  
48  /// Create a disconnected agent.
49  pub fn new(id: String) -> Agent(Disconnected) {
50    Agent(id: id, label: DisconnectedLabel)
51  }
52  
53  /// Transition from disconnected to handshaking.
54  pub fn handshake(agent: Agent(Disconnected)) -> Agent(Handshaking) {
55    Agent(id: agent.id, label: HandshakingLabel)
56  }
57  
58  /// Transition from handshaking to mounted.
59  pub fn mount(agent: Agent(Handshaking)) -> Agent(Mounted) {
60    Agent(id: agent.id, label: MountedLabel)
61  }
62  
63  /// Transition from mounted to live.
64  pub fn go_live(agent: Agent(Mounted)) -> Agent(Live) {
65    Agent(id: agent.id, label: LiveLabel)
66  }
67  
68  /// Transition from live to draining.
69  pub fn drain(agent: Agent(Live)) -> Agent(Draining) {
70    Agent(id: agent.id, label: DrainingLabel)
71  }
72  
73  /// Transition from draining to terminated.
74  pub fn terminate(agent: Agent(Draining)) -> Agent(Terminated) {
75    Agent(id: agent.id, label: TerminatedLabel)
76  }
77  
78  /// Return the agent id.
79  pub fn id(agent: Agent(state)) -> String {
80    agent.id
81  }
82  
83  /// Return the lifecycle label.
84  pub fn lifecycle(agent: Agent(state)) -> Lifecycle {
85    agent.label
86  }
87  
88  /// Convert a lifecycle label to a stable string.
89  pub fn lifecycle_to_string(lifecycle: Lifecycle) -> String {
90    case lifecycle {
91      DisconnectedLabel -> "disconnected"
92      HandshakingLabel -> "handshaking"
93      MountedLabel -> "mounted"
94      LiveLabel -> "live"
95      DrainingLabel -> "draining"
96      TerminatedLabel -> "terminated"
97    }
98  }