Compare commits
5 Commits
05e192ca70
...
v1.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
| ef639679d1 | |||
| 8c4dc0ee93 | |||
| 2301c57768 | |||
| cfe9ec9017 | |||
| 5f50b881ca |
@@ -41,10 +41,10 @@ So you can never accidentally run without auth. Rotate by editing the token and
|
|||||||
|
|
||||||
## Protocol version
|
## Protocol version
|
||||||
|
|
||||||
The wire protocol has a version (`PROTOCOL_VERSION`, currently **1**), so the website and sidecar detect a mismatch immediately instead of failing in strange ways when a message shape changes.
|
The wire protocol has a version (`PROTOCOL_VERSION`, currently **3**), so the website and sidecar detect a mismatch immediately instead of failing in strange ways when a message shape changes.
|
||||||
|
|
||||||
- Every response carries an `X-UOLink-Version: 1` header.
|
- Every response carries an `X-UOLink-Version: 3` header.
|
||||||
- `/health` and the WebSocket `ws.hello` include `"protocol": 1`.
|
- `/health` and the WebSocket `ws.hello` include `"protocol": 3`.
|
||||||
- If a request sends `X-UOLink-Version` and it disagrees with the sidecar, the request is rejected **409 Conflict** with `{sidecar_protocol, client_protocol}` so the mismatch is obvious.
|
- If a request sends `X-UOLink-Version` and it disagrees with the sidecar, the request is rejected **409 Conflict** with `{sidecar_protocol, client_protocol}` so the mismatch is obvious.
|
||||||
|
|
||||||
Bump `PROTOCOL_VERSION` in `main.rs` whenever an event or endpoint's shape changes.
|
Bump `PROTOCOL_VERSION` in `main.rs` whenever an event or endpoint's shape changes.
|
||||||
|
|||||||
@@ -24,7 +24,12 @@ use tracing_subscriber::EnvFilter;
|
|||||||
/// v2 (Protocol 2.0): adds the account-provisioning verbs/endpoints (`POST /accounts/create`,
|
/// v2 (Protocol 2.0): adds the account-provisioning verbs/endpoints (`POST /accounts/create`,
|
||||||
/// `DELETE /link/:account`) and their events. Outbound event kinds are additive, so a v1 website
|
/// `DELETE /link/:account`) and their events. Outbound event kinds are additive, so a v1 website
|
||||||
/// keeps working against the live feed; the new *endpoints* require a v2 sidecar.
|
/// keeps working against the live feed; the new *endpoints* require a v2 sidecar.
|
||||||
pub const PROTOCOL_VERSION: u32 = 2;
|
///
|
||||||
|
/// v3 (Protocol 3.0): adds `world.ruleset`, `points.board` and `vendor.listing` /
|
||||||
|
/// `vendor.listing.remove`, with the `GET /ruleset`, `/points` and `/market` reads that serve them
|
||||||
|
/// from the store. Same shape as the v2 bump — the kinds are additive, the endpoints are not — and
|
||||||
|
/// there is deliberately no feature-negotiation array: v3 implies all three kinds.
|
||||||
|
pub const PROTOCOL_VERSION: u32 = 3;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
@@ -257,11 +262,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
// lets a reader tell a re-send from an actual config change.
|
// lets a reader tell a re-send from an actual config change.
|
||||||
"world.ruleset" => {
|
"world.ruleset" => {
|
||||||
if let Err(e) = event_store
|
if let Err(e) = event_store
|
||||||
.upsert_ruleset(
|
.upsert_ruleset(ev.value.get("rev").and_then(|r| r.as_str()), &text, t)
|
||||||
ev.value.get("rev").and_then(|r| r.as_str()),
|
|
||||||
&text,
|
|
||||||
t,
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
tracing::warn!(error = %e, "failed to upsert ruleset");
|
tracing::warn!(error = %e, "failed to upsert ruleset");
|
||||||
|
|||||||
@@ -299,7 +299,12 @@ impl Store {
|
|||||||
/// `world.ruleset` frame per connect describing how it is configured, and only the latest one
|
/// `world.ruleset` frame per connect describing how it is configured, and only the latest one
|
||||||
/// matters. `rev` is the shard's FNV-1a of the body, kept so a reader can tell "same ruleset,
|
/// matters. `rev` is the shard's FNV-1a of the body, kept so a reader can tell "same ruleset,
|
||||||
/// re-sent on reconnect" from "the operator changed something" without diffing the JSON.
|
/// re-sent on reconnect" from "the operator changed something" without diffing the JSON.
|
||||||
pub async fn upsert_ruleset(&self, rev: Option<&str>, json: &str, t: i64) -> anyhow::Result<()> {
|
pub async fn upsert_ruleset(
|
||||||
|
&self,
|
||||||
|
rev: Option<&str>,
|
||||||
|
json: &str,
|
||||||
|
t: i64,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
sqlx::query(
|
sqlx::query(
|
||||||
"INSERT INTO ruleset (id, rev, json, updated_t) VALUES (1, ?, ?, ?)
|
"INSERT INTO ruleset (id, rev, json, updated_t) VALUES (1, ?, ?, ?)
|
||||||
ON CONFLICT(id) DO UPDATE SET rev = excluded.rev, json = excluded.json, updated_t = excluded.updated_t",
|
ON CONFLICT(id) DO UPDATE SET rev = excluded.rev, json = excluded.json, updated_t = excluded.updated_t",
|
||||||
|
|||||||
Reference in New Issue
Block a user