Roll out and roll back
Swap the rules a server holds without a restart. A broken ruleset is refused and the old one keeps serving. Rolling back is serving the old bundle again.
Rolling out a rule means replacing the bundle a running application holds. The rule server
reloads its rules directory on SIGHUP or on a schedule, and it only swaps when every ruleset
loads. Rolling back means putting the previous bundle back: it has the same checksum as before, so
every cache that still holds it stays valid.
Hands-on
This exchange continues the rule server session of Publish and version. The client still holds the ETag of version 1.0.0.
$ # orders.ruleset.yaml is now version 1.1.0 with maxQuantity 8
$ kill -HUP <server pid>
server log: {"level":"info","message":"rules reloaded","trigger":"SIGHUP","rulesets":2}
> GET /rulesets/shop.orders/manifest?channel=client
> If-None-Match: "sha256:4583c90bbfcacb54bf78e11d9e8190ecc086ce4b69aade609b7a0928d452ea82-client"
< 200
< etag: "sha256:c91b126e7709422a0971fdebbb4e82deeb781864bdf9d2d98e9e1a009ee233e6-client"
< cache-control: public, max-age=0, must-revalidate
{
"id": "shop.orders",
"version": "1.1.0",
"checksum": "sha256:c91b126e7709422a0971fdebbb4e82deeb781864bdf9d2d98e9e1a009ee233e6",
"channel": "client",
"rules": [
"order.quantity.max"
]
}
$ # a broken orders.ruleset.yaml reaches the rules directory
$ kill -HUP <server pid>
server log: {"level":"error","message":"reload refused, still serving the previous rules: PATH_UNKNOWN: path data.quantty is not in the Order schema","trigger":"SIGHUP"}
> GET /rulesets
< 200
[
{
"id": "shop.orders.eu",
"version": "1.0.0",
"checksum": "sha256:46706e19a5fbc1f0beff62c414cf0d0f5a204795803732c36ac3f4acde40886a"
},
{
"id": "shop.orders",
"version": "1.1.0",
"checksum": "sha256:c91b126e7709422a0971fdebbb4e82deeb781864bdf9d2d98e9e1a009ee233e6"
}
]
$ # roll back: put version 1.0.0 back
$ kill -HUP <server pid>
server log: {"level":"info","message":"rules reloaded","trigger":"SIGHUP","rulesets":2}
> GET /rulesets/shop.orders/manifest?channel=client
> If-None-Match: "sha256:4583c90bbfcacb54bf78e11d9e8190ecc086ce4b69aade609b7a0928d452ea82-client"
< 304
< etag: "sha256:4583c90bbfcacb54bf78e11d9e8190ecc086ce4b69aade609b7a0928d452ea82-client"
< cache-control: public, max-age=0, must-revalidateRead it in three parts:
- Roll out. Version 1.1.0 lowers the limit to 8. After the reload, the old ETag no longer matches, so the client gets the new manifest with the new checksum.
- A broken file. A ruleset with a typo reaches the directory. The reload is refused with the
reason, and the server keeps serving 1.1.0. The child ruleset
shop.orders.eushows a new checksum too: it inherits fromshop.orders, so a parent change is a child change. - Roll back. Version 1.0.0 goes back. Its checksum is the one from before, so the client's
original ETag matches again and the answer is
304.
For an embedded runtime, roll out by deploying the service with the new bundle, or let a holder reload it on a schedule (see Caching and refreshing rules). Roll back the same way, with the previous bundle from your store.
Done when
- After the roll-out,
/rulesetsand the manifest show the checksum of the new bundle. - A ruleset that fails to load is refused, and the previous checksum is still served.
- After a roll-back, the served checksum is exactly the old one.
Go deeper
- Ship a rule change, steps "Roll out" and "Verify, or roll back".
- Deploy the rule server on Kubernetes.
Enforce in the UI and the API
The browser evaluates for feedback; the server evaluates for the decision. A denied operation gets 422 and nothing is saved.
Monitor
Log the checksum of the rules behind every decision, and alert on RULE-EVALUATION-ERROR, the finding a rule raises when it cannot be evaluated.