Skip to content

feat: P1.5 engine diag counters — submitted/terminal/overflowRej on EGRESS-DIAG#42

Merged
emrebulutlar merged 1 commit into
mainfrom
feat/engine-diag-counters
Jul 3, 2026
Merged

feat: P1.5 engine diag counters — submitted/terminal/overflowRej on EGRESS-DIAG#42
emrebulutlar merged 1 commit into
mainfrom
feat/engine-diag-counters

Conversation

@emrebulutlar

Copy link
Copy Markdown
Member

Part of #32 (P1.5). The correctness counters the P1 gate harness reads, modeled on the existing zero-alloc egress diag pattern:

  • ordersSubmitted: CreateOrder commands accepted off ingress (plain long in SbeDemuxer; written and read on the cluster service thread only)
  • ordersTerminalized: terminal OrderStatus events (FILLED/CANCELLED/REJECTED) counted in MatchEventPublisher BEFORE the Disruptor, so egress shedding cannot hide a terminalization
  • overflowRejects: pre-plumbed AtomicLong + new OrderRejectReason.OVERFLOW=5. Stays 0 until P1.1 ([P1.1] FixedPoint.multiply: product-overflow-safe + throw; route match notional sites #30) makes FixedPoint.multiply throw on true overflow and routes the reject here; the harness records the 0 baseline

All three appear on the periodic EGRESS-DIAG leader-health: line and the role-transition dump. No allocation added to the hot path; strings stay confined to the 5s diag timer. mvn clean verify green.

🤖 Generated with Claude Code

…GRESS-DIAG

Adds the correctness counters the P1 gate harness reads (match#32), modeled
on the existing zero-alloc egress diag pattern:

- ordersSubmitted: CreateOrder commands accepted off ingress (plain long in
  SbeDemuxer; written and read on the cluster service thread only)
- ordersTerminalized: terminal OrderStatus events (FILLED/CANCELLED/REJECTED)
  counted in MatchEventPublisher BEFORE the Disruptor, so egress shedding
  cannot hide a terminalization (plain long, service thread only)
- overflowRejects: pre-plumbed AtomicLong + new OrderRejectReason.OVERFLOW=5.
  Stays 0 until P1.1 (match#30) makes FixedPoint.multiply throw on true
  overflow and routes the reject here; the harness records the 0 baseline.

All three appear on the periodic EGRESS-DIAG leader-health line and the
role-transition dump (submitted=/terminal=/overflowRej=). No allocation
added to the hot path; strings stay confined to the 5s diag timer.

Part of match#32 (P1.5).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@emrebulutlar
emrebulutlar merged commit d822e74 into main Jul 3, 2026
1 check passed
emrebulutlar added a commit that referenced this pull request Jul 3, 2026
…LOW rejects at admission (#52)

FixedPoint.multiply picked its path by the FIRST operand's magnitude, so
multiply(smallQty, largePrice) wrapped silently (any qty-first notional over
~$92B raw product), products in [2^63, 2^64) came out NEGATIVE (the ~$922-
$1844 band that spuriously NOTIONAL_TOO_SMALL-rejects ~3% of typical orders
via the OMS risk path), and the 128-bit branch divided by an APPROXIMATION
of 2^64/SCALE. divide's wide path wrapped on both of its terms.

Both are now exact with truncation toward zero, selecting the wide path by
whether the PRODUCT fits 64 bits (operand order can never matter again), and
the wide path is an exact unsigned 128/64 division (Hacker's Delight divlu).
When the true result does not fit a signed long they throw
FixedPoint.OverflowException (stackless: cheap under hostile input) — wrong
money is never returned.

Engine routing: LIMIT / LIMIT_MAKER / UPDATE admission validates the notional
alongside validateLimitPrice and rejects with OrderRejectReason.OVERFLOW
(counted on the EGRESS-DIAG line as overflowRej, replacing the #42
pre-plumbed AtomicLong). Since no order with an unrepresentable notional can
enter the book, every downstream cost product is bounded by an admitted
notional and cannot overflow mid-match; the market-buy budget divisions
(the only remaining throw sites) stop matching deterministically instead.

Property tests: BigInteger oracle over 1M+ samples — edge grid, financial
ranges (prices >= $10M, qty to book capacity), products concentrated in
2^62..2^66 (the band and the old approximate path), uniform random longs,
both operand orders every time, multiply/divide round-trip. Determinism
corpus: unchanged (no golden shifts).

Fixes #30.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant