Topic
The versions of a running app
An app runs one version, and may hold others that can still be loaded, so that a page of an older version goes on working.
const version = await app.add('.tent/build/0f3c9a...')
const { hard, steps } = await app.switch(version)
app.versions() // [{ id, running, needed, addedAt }]
await app.drop(older)| Member | Does |
|---|---|
app.add(bundleFolder) | Makes one more version loadable, and answers its id. code.T0011 for a bundle whose description does not pass or whose code cannot be loaded. In the mode development the version is run from that folder, with no copy |
app.switch(version) | Makes a loadable version the running one. Its table changes are applied inside one write. A table change that is refused fails the switch with its finding, code.T2001 to code.T2004, and leaves everything as it was |
app.versions() | Every version that can be loaded. needed says that a live connection still holds a watch that names it |
app.drop(version) | A version that is neither running nor needed can be loaded no more. It answers whether the version was dropped |
app.show(findings) | In the mode development: what every open page shows as an overlay. An empty list takes the overlay away. code.T0013 in any other mode |
A call, a read, a watch and a request for a screen that names a version which can be loaded is served by that version. One that names any other is answered code.T0007, with the id of the running version, and the page follows that one and sends its call once more. A call that names no version is served by the running one.
On an app of several machines every reader holds every version that can be loaded, so a page of an older version is served there too. app.add on the writer tells each reader at once, and the reader fetches the files it lacks, loads the version and says that it holds it. app.switch waits, before its write, until each joined reader holds the version, for versionWait (60 seconds) at most: the link of a reader that does not hold it by then is closed, and that reader joins again and is not current until it does. The write of the switch carries its table changes and the version, and a reader applies both and runs the version before it says that it holds the write. A reader drops a version that its writer names no more. app.add, app.switch and app.drop on a reader are code.T0030. Where the new version lets a reader be behind for a shorter time, the writer still waits for a reader that was cut off before the switch by the longer one.
On an app that keeps a data file for each tenant, the write of a switch changes the shared file, and each file of a tenant is brought up after it, by a pass that reaches every file, a few at a time. Before the write the shared file names the check that stands, and every file is held against the steps: a file that fits is held to them from then on, so that a write which would break one is refused with code.T2107, by the version that still runs too. One file that does not fit refuses the switch with code.T2001, which names the tenant and the count: the check is taken away, no hold counts any more, and nothing else is changed. A switch that is taken answers behind, the count of files its pass began with. While a file is still behind, or failed, a switch that changes a tenant table is not taken: it answers refused: 'behind' with the count, and changes nothing. A switch back to the layout that the last switch came from is taken at once, whether its pass still runs or has ended: the pass turns round, and each file that was brought up is brought back by the steps it came by, so a column or a table that the switch renamed takes its old name again with its values. Until every file is back, any other switch that changes a tenant table answers refused: 'behind'. A switch that changes a tenant table takes a backup first, as one that changes the shared file does. app.switch(version, { dry: true }) counts what does not fit, holds nothing, answers the count of files that are behind, and changes nothing: so a program waits for a pass. A file that cannot be brought up is marked failed, and tent data files --retry <tenant id> tries it again. An engine that was stopped while a check stood takes it away when it opens, with its holds. A version in which a table gains or loses tenant while it holds rows is taken with app.switch(version, { move: true }): every write of such a table waits, the rows are added where they go, a tenant at a time, each with its id, its two moments and its kept earlier versions, a read is answered meanwhile from where the rows stand, and the write of the switch ends the move. A raw SQL write that states no table is taken where the rows still stand, and the rows are added anew before the write of the switch; from then until that write it waits too. A reader follows the move of its writer. A move is taken for a table that gains or loses tenant, through app.switch, command.publish and command.dev. An app on one machine that keeps no file yet opens its files with the first version that has a tenant table; one with readers takes no such move yet. tent start --move opens on the version the data ran and switches with move. A table whose tenants are of another table than before is moved by two switches with move: one to a version in which it states no tenant, which brings its rows into the shared file, then one to the version in which its tenants are of the other table. A moved row keeps its id and its two moments and fires no trigger, the holds of its files are written anew with its tenant, and the values that work filled for it move with it. A row that a unique rule of the whole app does not take undoes the move, and the switch is refused with code.T2001, which names the table, the tenant and the count. An engine that was stopped in the middle of a move removes what it added when it opens. A file that a move emptied, under a table that no tenant table names any more, is removed by the upkeep. command.dev moves the rows of the development data at once.
A switch is hard when one of its table changes leaves the older versions unable to read or write the tables: a table or a column that is renamed or retired, a column that becomes required or unique, a type that is checked against the rows. A hard switch drops the older versions at once, and their pages are told to load anew. In the mode development a page is served by the running version only, and every switch tells every open page.