Skip to content

Commit 0d303a2

Browse files
authored
Stop a ref resolving against a dead computer session (#173)
The generation a computer stamps on a snapshot is unique only within one run of it. A replaced container counts from one again, so a ref the model is still holding from the run before matches a row nothing has overwritten, and the element handed to the policy belongs to a page that no longer exists. The audit row then names that element too, so the trail agrees with the wrong decision. `resetComputer` clears the row for exactly this reason and is the only thing that does. Replacing a computer whose image has changed does not, and the server is never told, so the row outlives the run that wrote it. That path is one I added earlier today, which turned a narrow race into something an upgrade walks every Bot through. A snapshot now carries the run that took it, read from the same `/ensure` that already locates the computer for every action. `resolve` refuses a ref whose run is not the current one, and a save from a different run replaces the row whatever its generation, because a new run counting from one is not a stale write to be refused: it is the only write that can be right. The supervisor had to start reporting it. `listOwned` carried `startedAt` and `ensure` did not, so the first version of this stored nothing and did nothing, and the unit tests passed anyway because their fake provider supplied a session the real one never sent. `State.StartedAt` rather than `Created`: a restart is a new run, since the browser has lost every page it had. Unknown is not mismatched. A provider that cannot report a run, which is a deployment with one shared computer and no supervisor, leaves the generation check exactly as it was. Closes #162.
1 parent 3fee5d1 commit 0d303a2

12 files changed

Lines changed: 2676 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,14 @@ Sessions survive and nobody signs in again.
211211
is unavailable never blocks a sign-in.
212212

213213
### Fixed
214+
- **A ref could resolve against a page from a computer that no longer existed.** The generation a
215+
computer stamps on a snapshot is unique only within one run of it, so a replaced container counts
216+
from one again and a ref the model is still holding matches a row nothing has overwritten. The
217+
policy then decides on an element from a dead page, and the audit row names it. Wiping a computer
218+
cleared the row for that reason and was the only thing that did; replacing one whose image changed
219+
did not, and the server was never told. A snapshot now carries which run of the computer took it,
220+
refs from an earlier run resolve to nothing, and the first snapshot of a new run replaces the old
221+
row however low its generation.
214222
- **A migration stamped in the future silently swallowed the next one.** Drizzle runs a migration only
215223
when its journal timestamp is later than the newest one the database has recorded, so a migration
216224
stamped ahead of real time raises that ceiling and every migration written after it is skipped
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
-- Which run of the computer a snapshot belongs to.
2+
--
3+
-- The generation a computer stamps on a snapshot only tells snapshots apart within one session. A
4+
-- replaced container counts from one again, so a ref the model still holds from the previous session
5+
-- matches a row the new one has not overwritten, and the policy decides against an element from a
6+
-- page that no longer exists.
7+
--
8+
-- `resetComputer` clears the row for exactly that reason, and it is the only thing that does. It is
9+
-- not the only way a computer is replaced: the supervisor replaces one whose image has changed, and
10+
-- the server is never told. So the row outlives the session that wrote it, and the generation cannot
11+
-- tell.
12+
--
13+
-- Nullable because a deployment with one shared computer and no supervisor has no session to report.
14+
-- There the comparison is skipped and the behaviour is what it was before this column.
15+
ALTER TABLE "computer_snapshot" ADD COLUMN "session" text;

0 commit comments

Comments
 (0)