Rule Cascade
LearnThe process, end to end

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.

roll out 1.1.0, refuse a broken file, roll back (real exchange)
$ # 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-revalidate

Read it in three parts:

  1. 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.
  2. 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.eu shows a new checksum too: it inherits from shop.orders, so a parent change is a child change.
  3. 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, /rulesets and 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

Course overview

On this page