Order Book Resynchronisation and initialState
This page explains how to tell a genuine XBID reset apart from an ETPA resynchronisation, and how your client should rebuild its order book in each case.
Background
ETPA forwards XBID order book updates to you. Each update carries a revisionNo, which is assigned by XBID, not by ETPA. ETPA passes it through unchanged.
You may see a "restate" (orders republished with initialState: true) in two different situations. They look alike, but you should tell them apart and handle them differently.
| Case 1: XBID reset | Case 2: ETPA resync | |
|---|---|---|
| Cause | XBID itself resets its state | ETPA briefly disconnects from XBID (e.g. a deployment on ETPA's side) |
| XBID during the event | Resets | Stays up; revisionNo keeps advancing |
revisionNo behaviour | Restarts at 0 | Continues / jumps ahead from the running stream |
| What to do | Your existing reset handling | Clear your book and rebuild from the initialState: true batch |
Case 1: Genuine XBID reset
XBID resets and revisionNo restarts at 0. Handle this with your existing XBID reset logic.
Case 2: ETPA resynchronisation
What happens
- ETPA disconnects from XBID, for example during a deployment on our side.
- XBID stays up and keeps processing. Its
revisionNokeeps advancing, but ETPA is offline and can't store or forward those updates. - When ETPA reconnects, your view of the book is out of date.
- ETPA fetches the current XBID state and republishes it to you with
initialState: true.
Why revisionNo jumps
revisionNo comes from XBID, so it does not reset to 0 during an ETPA resync. It carries on from wherever XBID has got to. You'll see it jump ahead by however many revisions happened while ETPA was disconnected. This is expected and does not mean data is corrupted.
How to process the resync
An
initialState: trueevent is not a complete book on its own. Each event holds one order. All theinitialState: trueorders together make up the new authoritative book.
Recommended handling:
- Spot the start of the resync. The first
initialState: trueevent arrives, and itsrevisionNocontinues from or jumps ahead of the running stream instead of restarting at0. - Clear the order book state you were holding.
- Rebuild the book from the
initialState: trueorders. Ignore everything you received before them. - Go back to normal delta processing after the batch. Because you rebuild the whole book from the whole batch, you don't need a separate boundary for each contract. Orders for different contracts may arrive mixed together in the batch, and that's fine, because the batch as a whole is the book.
Quick reference: telling the cases apart
revisionNo is the signal that separates the two cases:
revisionNorestarts at0→ genuine XBID reset → use your existing reset handling.initialState: trueandrevisionNocontinues or jumps ahead → ETPA resync → clear the book and rebuild from theinitialStatebatch.
on event:
if event.revisionNo == 0 and lastRevisionNo > 0:
handleXbidReset() # Case 1
else if event.initialState and not inResync:
inResync = true
clearOrderBook() # Case 2: start of batch
applyOrder(event)
else if event.initialState and inResync:
applyOrder(event) # Case 2: rest of batch
else:
inResync = false
applyDelta(event) # normal processing
lastRevisionNo = event.revisionNo
This pseudocode is only an illustration. Adapt it to your own client and how it processes contracts.