Class: SpreeCmCommissioner::WaitingRoom::Positions::Stamp

Inherits:
Object
  • Object
show all
Extended by:
ServiceModuleThrowable
Includes:
Spree::ServiceModule::Base, FirestoreConnection
Defined in:
app/services/spree_cm_commissioner/waiting_room/positions/stamp.rb

Overview

Stamps queue positions onto waiting-guest Firestore docs so the app can render each guest's place in line ("N people ahead of you" = position - frontier_position). Walks the day partitions oldest-first, assigning each not-yet-stamped doc a continuous global position starting from the live current high-water mark (write-once — a doc is never restamped once it has a position), and commits in Firestore batches to stay under the 10 MiB/commit payload bound.

Also computes frontier_position here, in the same run as position, so both numbers feeding the app's subtraction come from one Firestore read window and can't disagree with each other. Both frontier_position (lobby:) and run telemetry (logs:) are returned in the result rather than written directly — WaitingRoom::AdvanceQueue owns the single combined lobby write and single combined logs write (merged with Heartbeat::Sweep's and Admission::CallGuests's own fields) so no step writes its own separate docs every tick.

Runs after Heartbeat::Sweep in WaitingRoom::AdvanceQueue — a stale doc resolved there frees a position for #frontier_position to advance past before this class ever reads it. That ordering is what lets frontier_position advance at all: an abandoned doc that never resolves freezes the count for every guest behind it.

Constant Summary collapse

STAMP_LIMIT =

Worth keeping >= Admission::CallGuests::MAX_CALLS_PER_RUN so that class's per-tick cohort is fully positioned by the time it queries — see that constant's comment. Not a correctness requirement (CallGuests's own position != nil filter is the actual guard), just throughput: falling behind here means CallGuests calls fewer than MAX_CALLS_PER_RUN some ticks.

(ENV['WAITING_ROOM_POSITION_STAMP_LIMIT'] || 3000).to_i
FIRESTORE_BATCH_SIZE =

Firestore bounds a batch update by payload size (10 MiB); this batch size leaves 500/commit far under that.

(ENV['WAITING_ROOM_FIRESTORE_BATCH_SIZE'] || 500).to_i

Instance Method Summary collapse

Methods included from ServiceModuleThrowable

call!

Methods included from FirestoreConnection

#firestore, #firestore_available?, #service_account

Instance Method Details

#call(firestore: nil) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'app/services/spree_cm_commissioner/waiting_room/positions/stamp.rb', line 36

def call(firestore: nil)
  started_at = Time.zone.now
  @firestore = firestore if firestore.present?

  stamp_positions
  success(
    stamped: @stamped.to_i,
    lobby: @lobby_fields,
    logs: @logs_fields.merge(
      started_at: started_at,
      finished_at: Time.zone.now
    )
  )
rescue StandardError => e
  failure(nil, e.message)
end