Skip to main content

Module bolt

Module bolt 

Source
Expand description

Neo4j’s Bolt protocol — the model is the graph database.

A client opens with the 4-byte magic 60 60 B0 17 and four version proposals; the server answers with the version it picked (Bolt 5.0–5.8, see messages::negotiate). From then on both sides exchange chunked PackStream messages. The model is asked exactly two things — may this login in (actions::BOLT_AUTHENTICATE_EVENT), and what does this Cypher query return (actions::BOLT_QUERY_EVENT) — and everything else is NetGet’s:

  • The state machine. CONNECTED → (HELLO) → AUTHENTICATION → (LOGON) → READY; RUN → STREAMING; PULL/DISCARD drain it back to READY; BEGIN → TX_READY, RUN → TX_STREAMING, COMMIT/ROLLBACK → READY; a FAILURE → FAILED, where every message but RESET and GOODBYE is answered IGNORED; RESET → READY from anywhere. A message that arrives ahead of a RESET the client already sent is IGNORED (the INTERRUPTED state), and a message the current state does not allow is a Neo.ClientError.Request.Invalid FAILURE and a close. Bolt 5.0 carries the credentials in HELLO and goes straight to READY.
  • Result streaming. The model answers RUN with every row at once; NetGet sends the column list in RUN’s SUCCESS, then as many RECORDs as each PULL’s n asks for with has_more, and the summary (type, db, stats, a bookmark for writes) at the end. Inside a transaction several results may be open at once and PULL/DISCARD address them by qid.
  • What costs no model call. HELLO, ROUTE (a single-server routing table naming the address the client dialled), BEGIN/COMMIT/ROLLBACK, RESET, LOGOFF, TELEMETRY, and the admin queries cypher-shell runs on every connect (CALL db.ping(), CALL dbms.licenseAgreementDetails(), CALL dbms.components()), so connecting costs nothing.
  • The password. With a password startup parameter NetGet compares the credential itself, in constant time, and a mismatch never reaches the model. The credential never appears in an event either way.

Three bounds, each refused before anything is allocated for it: the handshake must arrive within first_byte_timeout_secs, a message is capped at packstream::MAX_MESSAGE_BYTES summed over its chunks, and PackStream nesting at packstream::MAX_PACKSTREAM_DEPTH. The read deadlines wrap the read, never the answer, so a query parked for a human under a manual rule is not closed by idle_timeout_secs.

On a backend failure, an unusable answer or no answer, the client gets FAILURE Neo.TransientError.General.DatabaseUnavailable with a fixed message (never the error text) and the connection stays usable after RESET — Bolt’s own recovery path. A refused login closes the connection, as Neo4j does.

Re-exports§

pub use packstream::MAX_MESSAGE_BYTES;
pub use packstream::MAX_PACKSTREAM_DEPTH;

Modules§

actions
Bolt actions: what the model is told, and what its answers become.
messages
Bolt’s handshake and messages: what a client may send, and the four things a server answers with (SUCCESS, RECORD, IGNORED, FAILURE).
packstream
PackStream — Bolt’s value encoding — and Bolt’s message chunking.
values
The model’s JSON answers → PackStream, and the client’s PackStream parameters → JSON.

Structs§

BoltConfig
Startup configuration shared by every connection.
BoltServer

Constants§

DEFAULT_NEO4J_VERSION
Neo4j version the server claims unless neo4j_version says otherwise.
FIRST_BYTE_TIMEOUT
How long a new connection may take to send its 20-byte handshake. Bolt is client-first and every driver sends it with the connect, so 30 seconds only ever matters for a peer that is not speaking Bolt at all.
IDLE_TIMEOUT
How long the server waits for the next message after the handshake. Drivers pool connections and leave them idle between queries; five minutes keeps a pooled connection useful without letting abandoned ones accumulate.