Quick Start

This takes about five minutes. You’ll feed the same events to Inorderly in different orders, with repeats, and see the same output and the same hash come back every time. You need the inorderly command from the download page.

1. Write Some Events

Inorderly reads one JSON event per line. Save these five lines as events.ndjson. They’re an order, its payment and its shipment from three services, a second order, and the first order again, the way a retried webhook would send it:

{"id":"o-1","producer":"checkout","time":1000,"data":{"total":42.5}}
{"id":"pay-1","producer":"payments","time":998,"parents":["o-1"],"data":{"paid":42.5}}
{"id":"ship-1","producer":"warehouse","time":1005,"parents":["pay-1"]}
{"id":"o-2","producer":"checkout","time":1003,"data":{"total":9}}
{"id":"o-1","producer":"checkout","time":1000,"data":{"total":42.5}}

Every event needs a producer, a time and an identity, here the id. The payments service’s clock runs a little behind, so the payment is stamped 998, before the order it pays for at 1000. It names the order in parents.

2. Order Them

inorderly -window 50 < events.ndjson
{"pos":1,"id":"o-1","producer":"checkout","time":1000,"data":{"total":42.5}}
{"pos":2,"id":"pay-1","producer":"payments","time":998,"parents":["o-1"],"data":{"paid":42.5}}
{"pos":3,"id":"o-2","producer":"checkout","time":1003,"data":{"total":9}}
{"pos":4,"id":"ship-1","producer":"warehouse","time":1005,"parents":["pay-1"]}

Four events, not five: the repeated order was dropped. The payment came straight after its order even though its clock said otherwise, and everything else is in time order. -window 50 says an event may arrive up to 50 time units behind the newest one seen.

A summary goes to standard error. Abridged:

{"hash": "sha256:693ba38c87d054811b01bdd9c30d9b3b22c5a5f53d9226e4f20d041fde1c1453", "in": 5, "ordered": 4, "duplicates": 1, "late": 0, ...}

3. Shuffle It

Reverse the file, or send every line twice, and check the hash:

tac events.ndjson | inorderly -window 50 -stats b.json | sha256sum
cat events.ndjson events.ndjson | inorderly -window 50 -stats c.json | sha256sum

Both print 693ba38c87d0…1c1453, the same as the first run. The hash in the summary is the SHA-256 of the output, so sha256sum and Inorderly agree.

A terminal running Inorderly three times on the same events: in file order, reversed with tac, and with every line sent twice. All three outputs have the same SHA-256, and the summaries count 1, 1 and 6 duplicates dropped.

4. Send Something Too Late

Add an order stamped 940 at the end, after events up to 1005 have been seen:

echo '{"id":"o-0","producer":"checkout","time":940}' > late.ndjson
cat events.ndjson late.ndjson | inorderly -window 50 -rejects rejects.ndjson

The output is the same four lines. 940 is more than 50 behind 1005, so the event is late, and Inorderly refuses it instead of slipping it in somewhere new. That’s what keeps the output repeatable. It’s counted in the summary and written to the rejects file:

{"reason":"late","input":"-","line":6,"event":{"id":"o-0","producer":"checkout","time":940}}

Add -strict and the command exits with status 3 whenever anything was refused, which is handy in a pipeline.

5. A Parent That Never Comes

printf '%s\n' \
  '{"id":"ship-2","producer":"warehouse","time":1010,"parents":["pay-9"]}' \
  '{"id":"o-3","producer":"checkout","time":1080}' | inorderly -window 50 -hold 20
{"pos":1,"id":"ship-2","producer":"warehouse","time":1010,"parents":["pay-9"],"missing":["pay-9"]}
{"pos":2,"id":"o-3","producer":"checkout","time":1080}

The shipment waited up to 20 time units (-hold) for its payment. It never came, so the shipment went out with missing naming it.

6. Survive a Crash

For long runs, give Inorderly a folder for checkpoints. Use files for input and output:

inorderly -in day.ndjson -out ordered.ndjson -window 500 -state ordered.state

Kill it at any point and run the same command again. It carries on from the last checkpoint, and the finished ordered.ndjson is byte for byte what one uninterrupted run would have written.

Where Next

  • The reference lists every flag, file and field.
  • The contract on GitHub states the ordering rules exactly.
  • inorderly demo runs the self-checking demo, with a hundred thousand events in twenty arrival orders.