Skip to content

_apply_delta_inplace invalidates the cached Orderbook view even when delta=0 (no-op mutation) #347

Closed

Description

@TexasCoding

Problem

The existing-level branch of _apply_delta_inplace unconditionally calls state.invalidate() whenever the price key already exists, even when delta == Decimal(0) (no-op delta) or when new_qty == existing_qty. For a high-frequency book the next subscribe_book iterator read then pays the O(n log n) sort + 2N OrderbookLevel validations rebuild that #244 was introduced to avoid.

The wire usually doesn't carry delta=0 frames, but OrderbookDeltaPayload.delta is a FixedPointCount with no >0 constraint, and rounding-induced redundant frames can produce the thrash. A single equality check would skip the wasted rebuild.

Evidence

  • kalshi/ws/orderbook.py:185-196:
if existing_qty is not None:
    new_qty = existing_qty + delta
    if new_qty <= 0:
        del levels[price]
    else:
        levels[price] = new_qty
    # #244: a side mutated; drop the cached Orderbook view so
    # the next `to_orderbook`/`get` rebuilds with the new side.
    state.invalidate()
elif delta > 0:
    levels[price] = delta
    state.invalidate()

Suggested fix

Guard the invalidate on actual mutation:

if existing_qty is not None:
    new_qty = existing_qty + delta
    if new_qty <= 0:
        del levels[price]
        state.invalidate()
    elif new_qty != existing_qty:
        levels[price] = new_qty
        state.invalidate()
    # else: delta == 0, dict unchanged — keep the cached view.
elif delta > 0:
    levels[price] = delta
    state.invalidate()

Add a regression test asserting state.cached_orderbook is not None after applying a delta=0 frame on a populated price level.

Source

Round-3 independent audit (reviewer: websocket).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    performancePerformance / hot-path concernpolishCode-quality and DX improvements; non-functionalwsWebSocket-related

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions