Repository navigation
Host design
The design for the host: the one process that builds the server from its configuration, checks that configuration and the database before it listens, and starts and stops everything in order. Step 3's first stage builds it, and Roadmap says how far that has got. Where the process runs and what a public deployment adds are on Server core design.
The server is one process, NexusTomorrow.Server, with one composition root that builds the gateway's listeners, the owners, the write-behind queue and the command layer. It won't start on a setting it can't use or a database that isn't migrated, and it stops in the reverse of the order it started, so every save that was queued commits.
The harness builds this same host in-process, so the composition the tests drive is the one that runs. A setting checked at start turns a mistake into a refusal to start, not a failure at the first login. And the shutdown order is what keeps saves whole: stop taking work, finish the work already taken, then wait for the database.
One composition root, shared by the server and the harness. The harness starts the same host with its own settings, on free loopback ports, with a fake clock.
Settings are checked when they're bound, and the host refuses to start on any that fail:
| Setting | Must be |
|---|---|
Persistence:ConnectionString |
Set |
Gateway:UnknownAccountSecret |
At least 32 bytes, in base64, and the same across restarts |
Gateway:WorldPublicAddress |
An IPv4 address: the world server's address the login server hands the client |
| The three client ports | Different from each other |
Realm:Id |
At most 16,383, because the character list carries it in 14 bits |
Realm:Name |
Set |
Migrating is its own step. The host refuses to start while any schema has migrations pending, and NexusTomorrow.Server migrate applies every schema's migrations and exits.
Start-up runs in order: check the migrations, start the write-behind queue, give the realm owner its first block of character ids, start the owners, and only then open the listeners. Nothing listens before what's behind it is running.
Shutdown is orderly: stop accepting connections and close the open ones, drain each owner's message queue, hand every character in the world back to the realm once the map side exists, wait for every queued save to commit, and exit.
Every listener binds to loopback unless it's configured otherwise, as Hosting requires.
The host keeps the clock. No code reads the system clock: the host supplies a TimeProvider, and the harness swaps in a fake one.
The watchdog runs in the host, once a second on the host's clock, and logs an owner that has stopped draining its queue. What counts as stalled is on Owners design.
The local console reads commands from the server's standard input and runs them through the command layer as the console, which holds every permission. It's on by default (Cli:Enabled), and stays off when input is redirected.
- Nothing in the design.
None recorded yet.
| Claim | Basis |
|---|---|
| The realm id's 14 bits | Established from the client: the character list's realm id field |
| The start-up and shutdown order | Designed; held by the host's own tests as it's built |
- None of its own. The questions that span systems are on Server core design.
Guides
Explanation
Reference
Design
- Server core design
- Roadmap
- Codec design
- Message audit design
- Host design
- Gateway design
- Owners design
- Persistence design
- Command layer design
- Harness design
About this wiki