postjevsql.git / crates / postjevsql-core

Chapter 8: postjevsql-core, the part that only thinks

If chapters 5 to 7 were the hands, this is the head. Every decision in here is a pure function: given these questions, this is how the row is sent; given these bytes, this is the cache key; given this clock reading and this word, this request may go now or must wait so long; given these answers, ask these Choices next. No Postgres, no network, no clock, no randomness. The caller supplies all of those as arguments.

That restriction is what makes the hard parts testable. The label-tree search, for one, is checked against an exhaustive search over every combination of answers, which would be hopeless if every step needed a database and a model on the other end. Here it is a unit test that runs in about a second on any laptop.

flowchart LR
  subgraph core["postjevsql-core (pure)"]
    B["batch: how a row is sent"]
    K["cache_key: what was sent, hashed"]
    T["token_ratio: tokens from characters"]
    G["gcra: may this request go now?"]
    LT["label_tree: Choice over a tree of labels"]
    SL["shortlist: Choice over a long flat list"]
    GA["gate: does any label fit?"]
  end
  ext["postjevsql (the judge)"] --> B
  ext --> K
  ext --> T
  ext --> LT
  ext --> SL
  pg["postjevsql-pg (ratelimit.rs)"] --> G
  LT --> GA
  SL --> GA

Aside: sans-I/O. The searches here are written in a style called sans-I/O: the search never sends anything. It says "ask these Choices", you go and ask them however you like, and you hand it the answers. It then says what to ask next, or that it is done. The extension drives it through Postgres and HTTP/2; the tests drive it with a closure that makes answers up. Same search, no idea which is which.

Try it. cargo test -p postjevsql-core, from a fresh clone, no database and no key. About fifty tests, in about a second.

For the people who maintain it

PathWhat
src/The six decisions, one file each, and the gate both searches share. Chapter 9.
BUCKThe library, and :test, its unit tests, run as plain rust_test. Its only dependencies are jev-protocol and sha2.
Cargo.tomlGenerated by tools/cargo-gen (chapter 20).

← Previous: Chapter 7, scan/ · Up: crates · Next: Chapter 9, postjevsql-core/src/ →