DbApp
The database layer's entry trait: the one an application on eezo-db alone extends.
object Main extends DbApp {
override def schema: Schema = AppSchema
override def boot(): Unit = transact { /* a job over rows */ }
}
The layer is declarative. The application names its schema and says what boot does; the framework builds the Database from DbInit's overrides, installs it around the program, and closes it after. main is inherited from Dispatch: sbt run runs the program once with a database installed, and sbt "run status|sync|freeze|migrate|reset|drop|dump|ddl" are the schema commands (design/cli.md §4). dev and routes are the http layer's and do not exist here: eezoDev on a database only application prints the unknown command line on every save, and a rerun on save loop for a job is sbt's own ~run.
A Database is installed only around what needs one. ddl, dump, freeze and help never touch it, so they work with the database down; the program and the other commands get one for their whole duration. Installing never waits on the network: the pool starts empty (initializationFailTimeout negative), so Database.connect returns at once and the pool fills in the background. It is deliberately not eager, as Phoenix is not: with Postgres down, dev keeps serving every page that needs no database, and sbt run fails on the first query that needs Postgres, after the acquire timeout, rather than refusing to start.
Attributes
- Source
- DbApp.scala
- Graph
-
- Supertypes
- Known subtypes
-
trait EezoApp
Members list
Value members
Abstract methods
The program: what sbt run does, once, with a Database installed. Abstract, because a database only application is its program. The umbrella supplies the http layer's default, which is to serve.
The program: what sbt run does, once, with a Database installed. Abstract, because a database only application is its program. The umbrella supplies the http layer's default, which is to serve.
Attributes
- Source
- DbApp.scala
The application's schema, object AppSchema extends Schema named here. Abstract: a database layer is its schema, and an application without one is a mistake.
The application's schema, object AppSchema extends Schema named here. Abstract: a database layer is its schema, and an application without one is a mistake.
Attributes
- Source
- DbApp.scala
Concrete methods
The commands this application answers, as first argument :: rest. Nil is program and is answered here, once, so no layer owns it. Each layer writes own orElse super.commands for its own commands, so the later mixin's arms are consulted first.
The commands this application answers, as first argument :: rest. Nil is program and is answered here, once, so no layer owns it. Each layer writes own orElse super.commands for its own commands, so the later mixin's arms are consulted first.
Attributes
- Definition Classes
- Source
- DbApp.scala
The Postgres schema the drift commands introspect. search_path is set per connection in databaseInit; this is the same name, told to the side that reads catalogs.
The Postgres schema the drift commands introspect. search_path is set per connection in databaseInit; this is the same name, told to the side that reads catalogs.
Attributes
- Source
- DbApp.scala
What help says after the command table and before its footer: the caveats that belong to no single row. Each layer writes own ++ super.notes, and they are kept apart from usage so a stacked application prints one table and then every layer's notes, rather than one layer's notes in the middle of the other's commands.
What help says after the command table and before its footer: the caveats that belong to no single row. Each layer writes own ++ super.notes, and they are kept apart from usage so a stacked application prints one table and then every layer's notes, rather than one layer's notes in the middle of the other's commands.
Attributes
- Definition Classes
- Source
- DbApp.scala
What sbt run does on this layer: boot with a Database installed around it. Concrete here and in the http layer both, so a trait that stacks the two inherits two and must say which one it means; the umbrella says this one. No override here, deliberately: see Dispatch.program.
What sbt run does on this layer: boot with a Database installed around it. Concrete here and in the http layer both, so a trait that stacks the two inherits two and must say which one it means; the umbrella says this one. No override here, deliberately: see Dispatch.program.
Attributes
- Source
- DbApp.scala
One row per command, for help. Each layer writes own ++ super.usage, and names only the spelling and the description: the columns are help's to lay out, once, over every layer's rows together, so no layer has to guess how wide the others' spellings are.
One row per command, for help. Each layer writes own ++ super.usage, and names only the spelling and the description: the columns are help's to lay out, once, over every layer's rows together, so no layer has to guess how wide the others' spellings are.
Attributes
- Definition Classes
- Source
- DbApp.scala
The lifecycle, scoped to one command: built, installed, closed. Final, and protected rather than private so the umbrella can wrap the dev server in it.
The lifecycle, scoped to one command: built, installed, closed. Final, and protected rather than private so the umbrella can wrap the dev server in it.
Attributes
- Source
- DbApp.scala
Inherited methods
Short on purpose. detached borrows a second connection while the caller still holds its first, so one thread can hold two, and a full pool can deadlock on itself; the timeout is the only thing that turns that into an error. HikariCP's own 30 seconds reads as a hang to whoever is waiting on the request, and a request that cannot get a connection in 5 seconds is better answered with a 500 than left open.
Short on purpose. detached borrows a second connection while the caller still holds its first, so one thread can hold two, and a full pool can deadlock on itself; the timeout is the only thing that turns that into an error. HikariCP's own 30 seconds reads as a hang to whoever is waiting on the request, and a request that cannot get a connection in 5 seconds is better answered with a 500 than left open.
Attributes
- Inherited from:
- DbInit
- Source
- DbInit.scala
Run on every connection the pool creates, not once on a borrowed one (DESIGN §8.7).
Run on every connection the pool creates, not once on a borrowed one (DESIGN §8.7).
This is where search_path, application_name and statement timeouts belong. Without it an application that works in a non-public schema silently splits in two: its own connections see one schema and eezo's see another, which shows up as a migration that appears not to have run.
Attributes
- Inherited from:
- DbInit
- Source
- DbInit.scala
Attributes
- Inherited from:
- DbInit
- Source
- DbInit.scala
Small on purpose. HikariCP's sizing rule is connections = cores * 2 + spindles, because Postgres does its work on CPU and disk, and connections beyond what those can serve only queue inside the database instead of in the pool, where queueing is cheaper. Virtual threads make requests cheap, not connections: thousands of requests waiting briefly on a small saturated pool is the intended shape, not a sign the pool is too small.
Small on purpose. HikariCP's sizing rule is connections = cores * 2 + spindles, because Postgres does its work on CPU and disk, and connections beyond what those can serve only queue inside the database instead of in the pool, where queueing is cheaper. Virtual threads make requests cheap, not connections: thousands of requests waiting briefly on a small saturated pool is the intended shape, not a sign the pool is too small.
Attributes
- Inherited from:
- DbInit
- Source
- DbInit.scala
Overridable, so a test or a second environment can point elsewhere without touching boot.
Overridable, so a test or a second environment can point elsewhere without touching boot.
Attributes
- Inherited from:
- DbInit
- Source
- DbInit.scala
Attributes
- Inherited from:
- DbInit
- Source
- DbInit.scala
Attributes
- Inherited from:
- Dispatch
- Source
- Dispatch.scala