@coda-console/kernel 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/schema.mjs CHANGED
@@ -1,9 +1,13 @@
1
1
  // The kernel's tables and every statement it runs on them. Keeping the statements in one place lets a test check the
2
2
  // query plan of each one: none of them may scan a table.
3
3
 
4
+ const UNENDED_CALL = "state IN ('sending', 'open')";
5
+ const UNENDED_RUN = "status IN ('working', 'input-required')";
6
+
4
7
  // Entry n upgrades the schema from version n to n + 1. Migrations only go forward: the first entry is the 0.1.0 baseline,
5
8
  // and no entry changes once released, since a database already past it would never run it again. A changed table adds
6
- // an entry at the end.
9
+ // an entry at the end. An entry is SQL text, or a function of the host's now() giving it, for one that needs the time it
10
+ // runs at.
7
11
  export const MIGRATIONS = [
8
12
  `CREATE TABLE kernel_calls (
9
13
  from_addr TEXT NOT NULL,
@@ -98,13 +102,20 @@ export const MIGRATIONS = [
98
102
  CREATE INDEX kernel_outbox_lane ON kernel_outbox (lane, pos);
99
103
  CREATE INDEX kernel_outbox_call ON kernel_outbox (call_from, call_id);
100
104
  CREATE INDEX kernel_outbox_from ON kernel_outbox (from_addr, pos);`,
105
+ // 0.3.0: since when an ended call or run has been kept only to tell a repeat, by the host's clock, for forget() (9).
106
+ // A row that ended before this migration counts from it: by the host's clock, not SQLite's, as a simulated world's is
107
+ // not real; a letter about it still owed moves it on once confirmed. Like the rest of a migration, the backfill is no
108
+ // statement of SQL: it visits every row, once.
109
+ now => `ALTER TABLE kernel_calls ADD COLUMN quiet_at INTEGER;
110
+ ALTER TABLE kernel_runs ADD COLUMN quiet_at INTEGER;
111
+ UPDATE kernel_calls SET quiet_at = ${now} WHERE NOT (${UNENDED_CALL});
112
+ UPDATE kernel_runs SET quiet_at = ${now} WHERE NOT (${UNENDED_RUN});
113
+ CREATE INDEX kernel_calls_quiet ON kernel_calls (quiet_at);
114
+ CREATE INDEX kernel_runs_quiet ON kernel_runs (quiet_at);`,
101
115
  ];
102
116
 
103
117
  export const META = 'CREATE TABLE IF NOT EXISTS kernel_meta (key TEXT PRIMARY KEY, value INTEGER NOT NULL)';
104
118
 
105
- const UNENDED_CALL = "state IN ('sending', 'open')";
106
- const UNENDED_RUN = "status IN ('working', 'input-required')";
107
-
108
119
  export const SQL = {
109
120
  version: "SELECT value FROM kernel_meta WHERE key = 'version'",
110
121
  setVersion: "INSERT INTO kernel_meta (key, value) VALUES ('version', ?) ON CONFLICT (key) DO UPDATE SET value = excluded.value",
@@ -112,30 +123,46 @@ export const SQL = {
112
123
  call: 'SELECT * FROM kernel_calls WHERE from_addr = ? AND id = ?',
113
124
  addCall: `INSERT INTO kernel_calls (from_addr, id, to_addr, op, digest, input, parent, lane, by_from, by_id, awaited, memo, state)
114
125
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'sending')`,
126
+ // An imported call was taken already: open, at version 0, so that the first status its reread hears is newer.
127
+ adoptCall: `INSERT INTO kernel_calls (from_addr, id, to_addr, op, digest, input, parent, lane, by_from, by_id, awaited, memo, state, status, rev)
128
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'open', 'working', 0) RETURNING *`,
115
129
  // A receipt says the callee took the call; the run it took is working at version 1 (C6).
116
130
  openCall: "UPDATE kernel_calls SET state = 'open', status = 'working', rev = 1 WHERE from_addr = ? AND id = ? AND state = 'sending'",
117
131
  hearCall: "UPDATE kernel_calls SET state = 'open', status = ?, rev = ?, asked = ?, asking = ?, progress = ? WHERE from_addr = ? AND id = ? RETURNING *",
118
- endCall: 'UPDATE kernel_calls SET state = ?, result = ?, error = ?, progress = ?, owed = 1, local = ? WHERE from_addr = ? AND id = ?',
132
+ endCall: 'UPDATE kernel_calls SET state = ?, result = ?, error = ?, progress = ?, owed = 1, local = ?, quiet_at = ? WHERE from_addr = ? AND id = ?',
119
133
  paidCall: 'UPDATE kernel_calls SET owed = 0 WHERE from_addr = ? AND id = ?',
120
134
  owedCalls: 'SELECT from_addr, id FROM kernel_calls WHERE owed = 1',
121
135
  openCalls: "SELECT * FROM kernel_calls WHERE state = 'open'",
122
136
  detach: 'UPDATE kernel_calls SET awaited = 0 WHERE from_addr = ? AND id = ?',
123
137
  // The caller ends the call itself and takes no result from it; a late outcome is kept apart (C12).
124
- abandonCall: "UPDATE kernel_calls SET state = 'failed', error = ?, local = 1, abandoned = 1 WHERE from_addr = ? AND id = ?",
138
+ abandonCall: "UPDATE kernel_calls SET state = 'failed', error = ?, local = 1, abandoned = 1, quiet_at = ? WHERE from_addr = ? AND id = ?",
125
139
  lateCall: 'UPDATE kernel_calls SET late = ?, owed = 1 WHERE from_addr = ? AND id = ?',
140
+ // A letter about an ended call or run has just left the outbox: a repeat of it may come until its retention (9).
141
+ quietCall: 'UPDATE kernel_calls SET quiet_at = ? WHERE from_addr = ? AND id = ? AND quiet_at IS NOT NULL',
126
142
  awaiting: `SELECT * FROM kernel_calls WHERE by_from = ? AND by_id = ? AND awaited = 1 AND ${UNENDED_CALL}`,
127
143
  calls: `SELECT * FROM kernel_calls WHERE from_addr = ? AND ${UNENDED_CALL} AND state = coalesce(?, state)`,
144
+ // An ended call whose handler has committed and about which no letter is owed, quiet since before the retention, is
145
+ // no longer needed to tell a repeat (9); an unended row is not quiet and is never taken.
146
+ forgetCalls: `DELETE FROM kernel_calls AS c WHERE quiet_at < ? AND owed = 0
147
+ AND NOT EXISTS (SELECT 1 FROM kernel_outbox AS o WHERE o.call_from = c.from_addr AND o.call_id = c.id)`,
128
148
 
129
149
  run: 'SELECT * FROM kernel_runs WHERE from_addr = ? AND id = ?',
130
150
  addRun: `INSERT INTO kernel_runs (from_addr, id, to_addr, op, digest, parent, awaited, root, status, rev)
131
151
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'working', 1)`,
152
+ // An imported run was taken at version 1, as a run is (C6); one waiting for input is on its first question. One that
153
+ // has ended is never quiet: it owes no outcome letter, so nothing here tells when its caller has the outcome (9).
154
+ adoptRun: `INSERT INTO kernel_runs (from_addr, id, to_addr, op, digest, parent, awaited, root, status, rev, asked, asking, result, error, progress)
155
+ VALUES (?, ?, ?, ?, ?, ?, ?, 0, ?, 1, ?, ?, ?, ?, ?) RETURNING *`,
132
156
  dropRun: 'DELETE FROM kernel_runs WHERE from_addr = ? AND id = ?',
133
157
  haltRun: 'UPDATE kernel_runs SET cancel_asked = 1 WHERE from_addr = ? AND id = ?',
134
158
  updateRun: 'UPDATE kernel_runs SET status = ?, asked = ?, asking = ?, progress = ?, rev = rev + 1 WHERE from_addr = ? AND id = ? RETURNING *',
135
159
  // Without a progress of its own, an outcome carries the run's last one (C4).
136
- endRun: `UPDATE kernel_runs SET status = ?, result = ?, error = ?, progress = coalesce(?, progress), rev = rev + 1
160
+ endRun: `UPDATE kernel_runs SET status = ?, result = ?, error = ?, progress = coalesce(?, progress), rev = rev + 1, quiet_at = ?
137
161
  WHERE from_addr = ? AND id = ? RETURNING to_addr, root, progress`,
138
162
  runs: `SELECT * FROM kernel_runs WHERE to_addr = ? AND ${UNENDED_RUN} AND status = coalesce(?, status)`,
163
+ quietRun: 'UPDATE kernel_runs SET quiet_at = ? WHERE from_addr = ? AND id = ? AND quiet_at IS NOT NULL',
164
+ forgetRuns: `DELETE FROM kernel_runs AS r WHERE quiet_at < ?
165
+ AND NOT EXISTS (SELECT 1 FROM kernel_outbox AS o WHERE o.call_from = r.from_addr AND o.call_id = r.id) RETURNING from_addr, id`,
139
166
 
140
167
  timer: 'SELECT * FROM kernel_timers WHERE from_addr = ? AND id = ?',
141
168
  timers: 'SELECT * FROM kernel_timers WHERE from_addr = ?',
@@ -152,6 +179,7 @@ export const SQL = {
152
179
  // Only the number of an answer taken is kept, and which question it answered (C8, S8).
153
180
  answer: 'SELECT 1 FROM kernel_answers WHERE from_addr = ? AND id = ?',
154
181
  addAnswer: 'INSERT INTO kernel_answers (from_addr, id, run_from, run_id, asked) VALUES (?, ?, ?, ?, ?)',
182
+ forgetAnswers: 'DELETE FROM kernel_answers WHERE run_from = ? AND run_id = ?',
155
183
 
156
184
  // A letter is identified by `seq` and ordered by `pos`: a letter that replaces another takes the other's `pos` (R3).
157
185
  owe: `INSERT INTO kernel_outbox (pos, from_addr, to_addr, lane, kind, call_from, call_id, envelope)