You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 01-actor-model.md
+10-10Lines changed: 10 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,8 +1,8 @@
1
-
# Step 1: The Actor Model — Commutative Grid Dispatch
1
+
# Step 1: The Actor Model: Commutative Grid Dispatch
2
2
3
3
## The Problem We're Solving
4
4
5
-
Two control centers — one in California, one in New York — each manage a portion of the national grid. Both maintain a copy of the **grid balance**: a signed integer representing net generation in megawatts (positive = excess, negative = deficit).
5
+
Two control centers, one in California and one in New York, each manage a portion of the national grid. Both maintain a copy of the **grid balance**: a signed integer representing net generation in megawatts (positive = excess, negative = deficit).
6
6
7
7
Operators at either location can issue dispatch commands:
8
8
-**Dispatch up**: bring more generation online (+MW)
@@ -29,7 +29,7 @@ The squiggly arrows (`~>`) are **physical connections** in Lingua Franca: they u
29
29
30
30
## The Code
31
31
32
-
See [`src/DistibutedPowerGrid1_Actor.lf`](src/DistibutedPowerGrid1_Actor.lf).
32
+
See [`src/Step1_Actor.lf`](src/Step1_Actor.lf).
33
33
34
34
The core reactor is `SimpleGridManager`:
35
35
@@ -80,9 +80,9 @@ Each grid manager receives commands from **both** operators and keeps its own co
80
80
81
81
---
82
82
83
-
## Why This Works — Sometimes
83
+
## Why This Works, Sometimes
84
84
85
-
The operation `balance += value` has a special mathematical property: it is **associative and commutative**. It doesn't matter what order the additions happen — the final sum is always the same.
85
+
The operation `balance += value` has a special mathematical property: it is **associative and commutative**. It doesn't matter what order the additions happen; the final sum is always the same.
86
86
87
87
This means that even though `gm1` and `gm2` may process the same two commands in different orders, they will eventually agree on the same balance. This property is called **eventual consistency**.
88
88
@@ -92,15 +92,15 @@ More formally, this design satisfies **ACID 2.0** properties (Helland & Campbell
92
92
-**I**dempotent: TCP guarantees exactly-once delivery, so each command is applied exactly once
93
93
-**D**istributed: state is maintained at multiple nodes
94
94
95
-
A datatype with these properties is called a **Conflict-Free Replicated Datatype (CRDT)** — one of the simplest CRDTs in existence.
95
+
A datatype with these properties is called a **Conflict-Free Replicated Datatype (CRDT)**. This example is one of the simplest CRDTs in existence.
96
96
97
97
---
98
98
99
99
## The Catch
100
100
101
-
This design would allow operators to curtail generation far below zero — a dangerous grid imbalance that could trip protective relays and cause a cascading blackout.
101
+
This design would allow operators to curtail generation far below zero, creating a dangerous grid imbalance that could trip protective relays and cause a cascading blackout.
102
102
103
-
Any **business logic** that enforces limits (e.g., "don't curtail if balance is already at its minimum threshold") breaks commutativity — and with it, our consistency guarantees.
103
+
Any **business logic** that enforces limits (e.g., "don't curtail if balance is already at its minimum threshold") breaks commutativity. That also breaks the consistency guarantee from this simple CRDT-style design.
104
104
105
105
That's what we explore next.
106
106
@@ -112,8 +112,8 @@ That's what we explore next.
112
112
113
113
2. What would happen if TCP delivery were *not* guaranteed? How would the ACID 2.0 / CRDT properties need to change?
114
114
115
-
3.Why does the CAL theorem (Consistency vs. Availability under Latency constraints) apply here? What is the partial order? [[More Reading]](https://arxiv.org/abs/2301.08906)
115
+
3.Now consider the potential effect of network delays in this example. How would network delays affect the consistency of this example?
116
116
117
117
---
118
118
119
-
**Next:**[Step 2 — When Operations Are Non-Commutative](02-inconsistency.md)
119
+
**Next:**[Step 2: When Operations Are Non-Commutative](02-inconsistency.md)
Copy file name to clipboardExpand all lines: 02-inconsistency.md
+8-8Lines changed: 8 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,4 +1,4 @@
1
-
# Step 2: When Operations Are Non-Commutative — The Consistency Problem
1
+
# Step 2: When Operations Are Non-Commutative: The Consistency Problem
2
2
3
3
## Adding Real Business Logic
4
4
@@ -10,7 +10,7 @@ Real grid operators enforce **safety constraints**. A typical rule:
10
10
>
11
11
> If a curtailment would push the balance below the threshold, reject it and log an **imbalance event** (which triggers automated protective relays in a real system).
12
12
13
-
Let's say our minimum safe threshold is **−200 MW**. Here is the updated reactor (See [`src/DistibutedPowerGrid2_Inconsistency.lf`](src/DistibutedPowerGrid2_Inconsistency.lf)).
13
+
Let's say our minimum safe threshold is **−200 MW**. Here is the updated reactor (See [`src/Step2_Inconsistency.lf`](src/Step2_Inconsistency.lf)).
14
14
15
15
16
16
```lf
@@ -59,17 +59,17 @@ This new operation is **not commutative**. The result of applying two commands d
3. Final balance at `gm1`: **−130 MW**. No imbalance event.
71
71
72
-
Since `gm1` and `gm2` receive these messages over physical (unordered) connections, they may each experience a different scenario. **They permanently disagree on the balance** — and worse, they may disagree on whether an imbalance event occurred.
72
+
Since `gm1` and `gm2` receive these messages over physical (unordered) connections, they may each experience a different scenario. **They permanently disagree on the balance**, and worse, they may disagree on whether an imbalance event occurred.
73
73
74
74
This is the fundamental consistency problem in distributed systems.
75
75
@@ -90,14 +90,14 @@ New York node: dispatch +100 ───────────
90
90
↓
91
91
gm2 final: -50 MW ✓ no event
92
92
93
-
But gm1 (-130) ≠ gm2 (-50) — INCONSISTENT STATE!
93
+
But gm1 (-130) ≠ gm2 (-50): INCONSISTENT STATE!
94
94
```
95
95
96
96
In a real grid, this inconsistency means the two control centers have **contradictory views of grid health**. Automated systems making decisions based on these views could take opposing corrective actions, worsening the situation.
97
97
98
98
---
99
99
100
-
## Fixing It — The Options
100
+
## Fixing It: The Options
101
101
102
102
We'll explore three approaches to fix the inconsistency issue:
103
103
@@ -121,4 +121,4 @@ The single-node approach defeats the purpose of having two control centers. So w
Copy file name to clipboardExpand all lines: 03-timestamps.md
+12-12Lines changed: 12 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,19 +1,19 @@
1
-
# Step 3: Logical Timestamps — Ordering Events Across the Grid
1
+
# Step 3: Logical Timestamps: Ordering Events Across the Grid
2
2
3
3
## The Core Insight
4
4
5
-
When a California operator curtails generation at the same physical instant that a New York operator dispatches generation, there is no objective "ground truth" about which happened first. Special relativity tells us the ordering can depend on the observer — and for events separated by thousands of kilometers, the difference in light travel time is measurable.
5
+
When a California operator curtails generation at the same physical instant that a New York operator dispatches generation, there is no objective "ground truth" about which happened first. Special relativity tells us the ordering can depend on the observer, and for events separated by thousands of kilometers, the difference in light travel time is measurable.
6
6
7
-
Fortunately, we don't need ground truth. We just need **both control nodes to agree on the same ordering** — and for that ordering to look reasonable to human operators. Logical timestamps achieve exactly this.
7
+
Fortunately, we don't need ground truth. We need **both control nodes to agree on the same ordering**, and for that ordering to look reasonable to human operators. Logical timestamps achieve exactly this.
8
8
9
9
---
10
10
11
11
## What Is Logical Time?
12
12
13
-
Lingua Franca assigns a **timestamp** to every message at the point it is created. In a federated (distributed) program, each node uses its **local physical clock** to assign timestamps. Clock synchronization protocols like NTP, PTP, or GPS ensure that these clocks are close to each other — within a bounded error `ε`.
13
+
Lingua Franca assigns a **timestamp** to every message at the point it is created. In a federated (distributed) program, each node uses its **local physical clock** to assign timestamps. Clock synchronization protocols like NTP, PTP, or GPS keep these clocks close to each other, within a bounded error `ε`.
14
14
15
15
A timestamp becomes a **logical time** because:
16
-
- When Node A sends a message with timestamp `t`, Node B processes it at logical time `t` — even if Node B's physical clock has already advanced past `t`.
16
+
- When Node A sends a message with timestamp `t`, Node B processes it at logical time `t`, even if Node B's physical clock has already advanced past `t`.
17
17
- Logical time is a shared reference frame that both nodes agree on, independent of physical clock drift.
18
18
19
19
---
@@ -38,21 +38,21 @@ op1.command -> gm1.in1
38
38
op1.command -> gm2.in1
39
39
```
40
40
41
-
This small change has a profound effect: LF now **guarantees** that both `gm1` and `gm2`handle every pair of commands in the same logical time order.
41
+
This small change has a profound effect: LF now gives both `gm1` and `gm2`the same logical timestamps and a deterministic rule for processing them, provided the coordination assumptions are met.
42
42
43
43
---
44
44
45
45
## Code
46
46
47
-
See [`src/DistibutedPowerGrid3_TimeStamped.lf`](src/DistibutedPowerGrid3_TimeStamped.lf). And here is what our system looks like:
47
+
See [`src/Step3_Timestamps.lf`](src/Step3_Timestamps.lf). And here is what our system looks like:
3. No other changes to the reactor logic — timestamp ordering is handled by the LF runtime
55
+
3. No other changes to the reactor logic; timestamp ordering is handled by the LF runtime
56
56
57
57
---
58
58
@@ -73,7 +73,7 @@ reaction(in1, in2) -> out {=
73
73
=}
74
74
```
75
75
76
-
Because the connection wiring is symmetric (California always feeds `in1`, New York always feeds `in2` at both managers), both managers give priority to the California operator at simultaneous timestamps. This is a deterministic policy — not the most fair one, but a consistent one.
76
+
Because the connection wiring is symmetric (California always feeds `in1`, New York always feeds `in2` at both managers), both managers give priority to the California operator at simultaneous timestamps. This is a deterministic policy. It may not be the fairest policy, but it is consistent.
77
77
78
78
---
79
79
@@ -151,11 +151,11 @@ If it is OK for these reports to be made late, then we can annotate the reaction
151
151
152
152
## The CAL Theorem
153
153
154
-
The waiting introduced by timestamps is not a bug — it is **fundamental**. The **CAL theorem** ([Lee et al., 2023](https://doi.org/10.1145/3609119)) states:
154
+
The waiting introduced by timestamps is not a bug; it is **fundamental**. The **CAL theorem** ([Lee et al., 2023](https://doi.org/10.1145/3609119)) states:
155
155
156
156
> It is impossible to achieve consistency without paying a price in **availability**, where the price is proportional to the latencies in the system.
157
157
158
-
"Availability" here means: how long must an operator wait before their dispatch command takes effect? The longer the `maxwait`, the more consistent the system — and the longer operators wait. We'll return to this in Step 6.
158
+
"Availability" here means: how long must an operator wait before their dispatch command takes effect? A larger `maxwait` can tolerate larger apparent latency, but operators may wait longer. We'll return to this in Step 6.
159
159
160
160
---
161
161
@@ -169,4 +169,4 @@ The waiting introduced by timestamps is not a bug — it is **fundamental**. The
169
169
170
170
---
171
171
172
-
**Next:**[Step 4 — Conservative Coordination with Null Messages](04-conservative.md)
172
+
**Next:**[Step 4: Conservative Coordination with Null Messages](04-conservative.md)
Copy file name to clipboardExpand all lines: 04-conservative.md
+9-11Lines changed: 9 additions & 11 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,4 +1,4 @@
1
-
# Step 4: Conservative Coordination — Chandy-Misra with Null Messages
1
+
# Step 4: Conservative Coordination: Chandy-Misra with Null Messages
2
2
3
3
## The Problem with Finite maxwait
4
4
@@ -33,17 +33,17 @@ LF supports this method via `maxwait = forever`:
33
33
gm1 = new GridManager()
34
34
```
35
35
36
-
With `maxwait = forever`, the grid manager will wait **indefinitely**— until it receives positive evidence from the remote node that no message with tag ≤ `g` is coming.
36
+
With `maxwait = forever`, the grid manager will wait **indefinitely** until it receives positive evidence from the remote node that no message with tag ≤ `g` is coming.
37
37
38
38
Of course, waiting forever sounds like a bad idea.
39
-
What if the remote `GridInterface`
40
-
How does that evidence arrive? That's where **null messages** come in.
39
+
What if the remote `GridInterface`has no real commands to send?
40
+
How does the evidence arrive? That's where **null messages** come in.
41
41
42
42
---
43
43
44
44
## Null Messages
45
45
46
-
In our grid, commands are sent only when operators issue dispatches or curtailments. If California issues no commands for 10 minutes, New York's manager has no evidence about California's timeline — and blocks forever under `maxwait = forever`.
46
+
In our grid, commands are sent only when operators issue dispatches or curtailments. If California issues no commands for 10 minutes, New York's manager has no evidence about California's timeline and blocks forever under `maxwait = forever`.
47
47
48
48
The fix: California's node sends **null messages** periodically. A null message says:
The timer fires every second. If no real command has arrived, a `0` is forwarded — which the grid manager interprets as "no change." This lets the grid manager advance its logical time by at least 1 second per second, bounding the wait.
81
+
The timer fires every second. If no real command has arrived, a `0` is forwarded, which the grid manager interprets as "no change." This lets the grid manager advance its logical time by at least 1 second per second, bounding the wait.
82
82
83
83
---
84
84
@@ -89,7 +89,7 @@ The timer fires every second. If no real command has arrived, a `0` is forwarded
89
89
-**Bounded wait**: the maximum wait is ~1 second (the null message period) plus network latency.
90
90
91
91
**What you give up:**
92
-
-**Availability under failure**: if the California `GridServer` crashes, it stops sending null messages. New York's manager blocks indefinitely — it cannot advance time because it has no proof that California won't send a message.
92
+
-**Availability under failure**: if the California `GridServer` crashes, it stops sending null messages. New York's manager blocks indefinitely because it has no proof that California won't send a message.
93
93
-**Network overhead**: null messages are sent every second even when there are no real commands. For a grid with hundreds of nodes, this multiplies.
94
94
95
95
This is the CAL theorem in action: **strong consistency costs availability when network behavior is unbounded**.
@@ -98,9 +98,7 @@ This is the CAL theorem in action: **strong consistency costs availability when
98
98
99
99
## Code
100
100
101
-
See [`src/DistibutedPowerGrid4_ChandyMisra.lf`](src/DistibutedPowerGrid4_ChandyMisra.lf). And here is what our system looks like:
102
-
103
-
And here is what our system looks like:
101
+
See [`src/Step4_Conservative.lf`](src/Step4_Conservative.lf). Here is what our system looks like:
0 commit comments