The other implementation behind the seam, so the store-window guarantee now has both: one loop, one message at a time, the same window deciding. What differs is where a held message lives, and that is the whole point of the move — the AMQP side keeps an unacknowledged delivery in this process, bounded by the prefetch and lost if the controller stops; this keeps eight bytes saying when the window opened, and the message stays the server's. Checked against a running server, seven claims that reasoning cannot answer: a report is heard and leaves the work queue; one the store cannot take is naked with a delay, stays in the stream, and is recorded when the store returns; one about a superseded declaration is settled without being acted on; one the store never takes is let go once the bound passes; a heartbeat is heard and nothing is persisted; and the enrolment answer reaches the address the request carried in its payload — the test design 25 §2 asks for, so the reason for that field cannot quietly become folklore. Three things the wiring forced into the open: **The controller could not have consumed a module event.** Its permissions granted no event subject to subscribe and no ack subject on the events stream, so every announcement would have been redelivered for ever, refused by the list it already had. Both narrow: each followed subject named, not `mesh.mod.*.>`. **The controller's consumers are not derived.** It files no manifest, so its authority cannot come from a declaration that does not exist; they sit beside the mesh's own streams and are asserted the same way. No max-deliver on CONTROL — the window's bound is the controller's, and a server that dead-lettered first would discard the push the stream exists to protect. **Channels, not callbacks.** The library would run a handler on its own goroutine, and the window's bookkeeping is unlocked because the AMQP loop never had two.
51 lines
2.3 KiB
Plaintext
51 lines
2.3 KiB
Plaintext
# Composed by the mesh controller. Do not edit: the next composition overwrites it.
|
|
# Accounts and permissions are derived from what each module declares and nothing
|
|
# else (novox/hq ADR 0043, design 29 §2).
|
|
|
|
port: 4222
|
|
http: 127.0.0.1:8222
|
|
|
|
tls {
|
|
cert_file: "/tls/tls.crt"
|
|
key_file: "/tls/tls.key"
|
|
ca_file: "/tls/ca.crt"
|
|
verify: true
|
|
}
|
|
|
|
jetstream {
|
|
store_dir: "/data"
|
|
}
|
|
|
|
accounts {
|
|
MESH {
|
|
users = [
|
|
{ user: "controller", password: "$2a$11$cccccccccccccccccccccc", permissions: {
|
|
publish: { allow: ["$JS.ACK.CONTROL.controller.>", "$JS.ACK.EVENTS.controller.>", "$JS.API.>", "mesh.build.>", "mesh.control.>", "mesh.node.>"] }
|
|
subscribe: { allow: ["$JS.API.>", "_INBOX.controller.>", "mesh.build.>", "mesh.control.>", "mesh.mod.mesh-catalog.event.module.mesh-catalog.catching-up", "mesh.mod.mesh-catalog.event.module.mesh-catalog.upgraded"] }
|
|
allow_responses: { max: 1, ttl: "1m" }
|
|
} }
|
|
{ user: "enrolment", password: "$2a$11$eeeeeeeeeeeeeeeeeeeeee", permissions: {
|
|
publish: { allow: ["mesh.control.enrol"] }
|
|
subscribe: { allow: [] }
|
|
} }
|
|
{ user: "node.one", password: "$2a$11$nnnnnnnnnnnnnnnnnnnnnn", permissions: {
|
|
publish: { allow: ["$JS.ACK.NODES.one.>", "mesh.control.one.>"] }
|
|
subscribe: { allow: ["_INBOX.node.one.>", "mesh.node.one.declare"] }
|
|
} }
|
|
{ user: "one.telegram", password: "$2a$11$tttttttttttttttttttttt", permissions: {
|
|
publish: { allow: ["$JS.ACK.EVENTS.one_telegram.>", "mesh.seat.telegram-sender.event.delivered", "mesh.seat.telegram-sender.event.failed"] }
|
|
subscribe: { allow: ["_INBOX.one.telegram.>", "mesh.mod.telegram.tool.status", "mesh.seat.telegram-sender.accept.send"] }
|
|
allow_responses: { max: 1, ttl: "1m" }
|
|
} }
|
|
{ user: "two.audit", password: "$2a$11$aaaaaaaaaaaaaaaaaaaaaa", permissions: {
|
|
publish: { allow: ["$JS.ACK.EVENTS.two_audit.>"] }
|
|
subscribe: { allow: ["_INBOX.two.audit.>", "mesh.mod.shop.event.order.placed"] }
|
|
} }
|
|
{ user: "two.shop", password: "$2a$11$ssssssssssssssssssssss", permissions: {
|
|
publish: { allow: ["$JS.ACK.EVENTS.two_shop.>", "mesh.mod.shop.event.order.placed", "mesh.seat.telegram-sender.accept.send"] }
|
|
subscribe: { allow: ["_INBOX.two.shop.>"] }
|
|
} }
|
|
]
|
|
}
|
|
}
|