Class: SpreeCmCommissioner::WaitingRoom::Sessions::Issue
- Inherits:
-
Object
- Object
- SpreeCmCommissioner::WaitingRoom::Sessions::Issue
- Extended by:
- ServiceModuleThrowable
- Includes:
- Spree::ServiceModule::Base, FirestoreConnection
- Defined in:
- app/services/spree_cm_commissioner/waiting_room/sessions/issue.rb
Constant Summary collapse
- SESSION_CREATION_LOCK_KEY =
'waiting_room_session_creation'.freeze
- WAITING_ROOM_SESSION_MAX_DURATION_IN_SECOND =
Soft ceiling on how long a session may keep renewing before it competes for capacity again (see #max_expired_at_ceiling and #renew_active_session). 600s default; HOLD_DURATION (8 min) + PAYMENT_LOCK_MIN_DURATION extension can push a genuinely active checkout to ~13 min, so this is a soft cap — past it, the session self-expires and the next call falls back to the full?-gated path, rather than being evicted outright.
(ENV['WAITING_ROOM_SESSION_MAX_DURATION_IN_SECOND'] || 600).to_i
- WAITING_ROOM_SESSION_EXPIRE_DURATION_IN_SECOND =
How long a session's token/expired_at is valid before it needs renewal. 3min default.
(ENV['WAITING_ROOM_SESSION_EXPIRE_DURATION_IN_SECOND'] || (60 * 3)).to_i
- WAITING_ROOM_BYPASS_HEADROOM_MULTIPLIER =
A verified bypasser is admitted past the normal max, but only up to this bounded headroom (max * multiplier) — never without limit — so a burst of stuck-payment returns can't push the protected pages far past capacity. Default 1.1 (10% headroom); 1 gates bypassers at max. See #bypass_full?.
(ENV['WAITING_ROOM_BYPASS_HEADROOM_MULTIPLIER'] || 1.1).to_f
- PERMITTED_DEVICE_ATTRIBUTES =
Device attributes the client may set on the session. device_id and device_fingerprint are real columns; the rest are virtual columns backed by public/private metadata (see WaitingRoomSession). Anything else the client sends is dropped so we never persist arbitrary payloads.
%w[ device_id device_fingerprint os_name os_version device_model device_manufacturer device_type device_environment app_version app_build timezone network_type ].freeze
Instance Attribute Summary collapse
-
#bypass_jwt ⇒ Object
readonly
Returns the value of attribute bypass_jwt.
-
#bypass_order_token ⇒ Object
readonly
Returns the value of attribute bypass_order_token.
-
#device_attributes ⇒ Object
readonly
Returns the value of attribute device_attributes.
-
#page_path ⇒ Object
readonly
Returns the value of attribute page_path.
-
#remote_ip ⇒ Object
readonly
Returns the value of attribute remote_ip.
-
#tenant_id ⇒ Object
readonly
Returns the value of attribute tenant_id.
-
#user ⇒ Object
readonly
Returns the value of attribute user.
-
#waiting_guest_firebase_doc_id ⇒ Object
readonly
Returns the value of attribute waiting_guest_firebase_doc_id.
Instance Method Summary collapse
-
#call(waiting_guest_firebase_doc_id:, remote_ip:, page_path: nil, tenant_id: nil, device_attributes: nil, bypass_jwt: nil, bypass_order_token: nil, user: nil) ⇒ Object
Three ways in here:.
Methods included from ServiceModuleThrowable
Methods included from FirestoreConnection
#firestore, #firestore_available?, #service_account
Instance Attribute Details
#bypass_jwt ⇒ Object (readonly)
Returns the value of attribute bypass_jwt.
11 12 13 |
# File 'app/services/spree_cm_commissioner/waiting_room/sessions/issue.rb', line 11 def bypass_jwt @bypass_jwt end |
#bypass_order_token ⇒ Object (readonly)
Returns the value of attribute bypass_order_token.
11 12 13 |
# File 'app/services/spree_cm_commissioner/waiting_room/sessions/issue.rb', line 11 def bypass_order_token @bypass_order_token end |
#device_attributes ⇒ Object (readonly)
Returns the value of attribute device_attributes.
11 12 13 |
# File 'app/services/spree_cm_commissioner/waiting_room/sessions/issue.rb', line 11 def device_attributes @device_attributes end |
#page_path ⇒ Object (readonly)
Returns the value of attribute page_path.
11 12 13 |
# File 'app/services/spree_cm_commissioner/waiting_room/sessions/issue.rb', line 11 def page_path @page_path end |
#remote_ip ⇒ Object (readonly)
Returns the value of attribute remote_ip.
11 12 13 |
# File 'app/services/spree_cm_commissioner/waiting_room/sessions/issue.rb', line 11 def remote_ip @remote_ip end |
#tenant_id ⇒ Object (readonly)
Returns the value of attribute tenant_id.
11 12 13 |
# File 'app/services/spree_cm_commissioner/waiting_room/sessions/issue.rb', line 11 def tenant_id @tenant_id end |
#user ⇒ Object (readonly)
Returns the value of attribute user.
11 12 13 |
# File 'app/services/spree_cm_commissioner/waiting_room/sessions/issue.rb', line 11 def user @user end |
#waiting_guest_firebase_doc_id ⇒ Object (readonly)
Returns the value of attribute waiting_guest_firebase_doc_id.
11 12 13 |
# File 'app/services/spree_cm_commissioner/waiting_room/sessions/issue.rb', line 11 def waiting_guest_firebase_doc_id @waiting_guest_firebase_doc_id end |
Instance Method Details
#call(waiting_guest_firebase_doc_id:, remote_ip:, page_path: nil, tenant_id: nil, device_attributes: nil, bypass_jwt: nil, bypass_order_token: nil, user: nil) ⇒ Object
Three ways in here:
Condition #1 — queued: Admission::CallGuests precreated the row when it called this guest, so they just find and renew that existing row (if necessary).
Condition #2 — the row exists but its max_expired_at ceiling has already passed. Reject outright rather than silently reviving it: the ceiling is a hard cap the server controls, not something a renewal retry should be able to extend (see WaitingRoomSession#past_ceiling?).
Condition #3 — bypassed the queue: lobby doc showed full: false / has_queue: false, so the app called createSession directly. The caller never touched this guest, no row exists yet, so they fall through to a normal create_new_session. A row that's lapsed (expired_at passed) but still under its own ceiling also lands here — the revival path in #create_new_session.
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'app/services/spree_cm_commissioner/waiting_room/sessions/issue.rb', line 55 def call(waiting_guest_firebase_doc_id:, remote_ip:, page_path: nil, tenant_id: nil, # rubocop:disable Metrics/ParameterLists device_attributes: nil, bypass_jwt: nil, bypass_order_token: nil, user: nil ) @waiting_guest_firebase_doc_id = waiting_guest_firebase_doc_id @remote_ip = remote_ip @page_path = page_path @tenant_id = tenant_id @device_attributes = device_attributes @bypass_jwt = bypass_jwt @bypass_order_token = bypass_order_token @user = user return failure(nil, 'must_provide_waiting_guest_firebase_doc_id') if waiting_guest_firebase_doc_id.blank? return failure(nil, 'must_provide_remote_ip') if remote_ip.blank? existing = SpreeCmCommissioner::WaitingRoomSession.find_by(guest_identifier: waiting_guest_firebase_doc_id) if existing&.active? success(room_session: renew_active_session(existing)) elsif existing&.past_ceiling? failure(nil, 'waiting_room_session_expired') else create_new_session end end |