It Survives the Process — by the Least Clever Method
5 minThrough part 4 the waiting count lived like this.
var waiting = 3;Kill the process and it is 3 again. Unplug the desk screen and the queue never happened.
Write it down
const _statePath = 'desk-state.json';
int _load() {
final f = File(_statePath);
if (!f.existsSync()) return 3;
final m = jsonDecode(f.readAsStringSync()) as Map<String, dynamic>;
return (m['waiting'] as num).toInt();
}
void _save(int waiting) =>
File(_statePath).writeAsStringSync(jsonEncode({'waiting': waiting}));And call it when the value changes.
waiting -= n;
_save(waiting);Why rewrite the whole file
One value changes and the whole file is rewritten. Inefficient. But it has a property.
It never leaves a half-written record. The write either happened or it did not. Die in the middle and the old file is still there.
A partial update is not like that. Edit one record in place and die, and a file that is neither is left, and the next boot fails to parse. From there, recovery is work.
At tens of thousands of records this does not hold. That is where a database belongs. Until then, this is the safest thing there is.
Which floor
State can live on one of three floors.
| Floor | Do several screens see one value | When the process dies |
|---|---|---|
| Inside the screen | no — a different value per screen | gone |
| The server process | yes | gone |
| Outside the server (file, DB) | yes | stays |
Through part 4 it was the second. This piece moves it to the third.
If you do not decide, you get the second. And the day that becomes a problem is usually at night.
Verification — actually kill the process
Persistence is not confirmed by seeing "saved." It is confirmed by disconnecting and reading again.
rm -f desk-state.json
ask step5 '...{"name":"desk.admit","arguments":{"count":2}}}' >/dev/null # process 1
ask step5 '...{"name":"desk.state","arguments":{}}}' > captures/s5.txt # process 2
grep -q 'waiting.*1' captures/s5.txt || die "the count did not survive a restart"ask starts a new process each time. When the first call ends, that process is gone.
step5 admitted 2, process ended, a new process still reads waiting 1The server log records it too.
course step5: up, state in desk-state.json (waiting=3)
course step5: up, state in desk-state.json (waiting=1)The second boot starts at 1.
Run it yourself
dart run bin/step5.dart
bash verify.shWhat to take
_loadand_save— including the default when the file is not there yet- Whole-file rewrite — never leaves a half-written record
- A restart round trip — confirm from a new process's read, not from a save log
Next
Let the screen know the value changed. Without it asking.
Run the sample
cd course-server dart pub get dart run bin/step5.dart