Class: SpreeCmCommissioner::WaitingRoomSessionCreator

Inherits:
BaseInteractor
  • Object
show all
Defined in:
app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb

Constant Summary collapse

SESSION_CREATION_LOCK_KEY =
7_331_001

Instance Method Summary collapse

Instance Method Details

#assign_token_and_create_session_to_dbObject



50
51
52
53
54
55
56
57
58
59
60
61
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 50

def assign_token_and_create_session_to_db
  # create or renew
  context.room_session = SpreeCmCommissioner::WaitingRoomSession.where(guest_identifier: waiting_guest_firebase_doc_id).first_or_initialize
  context.room_session.assign_attributes(
    jwt_token: context.jwt_token,
    expired_at: expired_at,
    remote_ip: remote_ip,
    page_path: page_path,
    tenant_id: tenant_id
  )
  context.room_session.save!
end

#callObject



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 9

def call
  return context.fail!(message: 'must_provide_waiting_guest_firebase_doc_id') if waiting_guest_firebase_doc_id.blank?
  return context.fail!(message: 'must_provide_remote_ip') if remote_ip.blank?

  # Advisory lock ensures the capacity check and session creation are atomic across all app instances.
  with_session_creation_lock do
    return context.fail!(message: 'sessions_reach_it_maximum') if full?

    generate_jwt_token
    assign_token_and_create_session_to_db
  end

  log_to_firebase

  # commented because of following bug: https://github.com/channainfo/commissioner/issues/2185
  # this job is already run every 1mn, disabling it still work.
  # call_other_waiting_guests
end

#call_other_waiting_guestsObject



70
71
72
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 70

def call_other_waiting_guests
  SpreeCmCommissioner::WaitingGuestsCallerJob.perform_later
end

#expired_atObject



74
75
76
77
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 74

def expired_at
  expired_duration = ENV['WAITING_ROOM_SESSION_EXPIRE_DURATION_IN_SECOND']&.presence&.to_i || (60 * 3)
  context.expired_at ||= expired_duration.seconds.from_now
end

#firestoreObject



79
80
81
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 79

def firestore
  @firestore ||= Google::Cloud::Firestore.new(project_id: [:project_id], credentials: )
end

#full?Boolean

Returns:

  • (Boolean)


28
29
30
31
32
33
34
35
36
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 28

def full?
  max = Rails.cache.fetch('waiting_room/max_sessions_count', expires_in: 1.hour) do
    fetcher = SpreeCmCommissioner::WaitingRoomSystemMetadataFetcher.new(firestore: firestore)
    fetcher.load_document_data
    fetcher.max_sessions_count_with_min
  end

  SpreeCmCommissioner::WaitingRoomSession.active.count >= max
end

#generate_jwt_tokenObject



45
46
47
48
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 45

def generate_jwt_token
  payload = { exp: expired_at.to_i }
  context.jwt_token = JWT.encode(payload, ENV.fetch('WAITING_ROOM_SESSION_SIGNATURE'), 'HS256')
end

#log_to_firebaseObject



63
64
65
66
67
68
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 63

def log_to_firebase
  SpreeCmCommissioner::WaitingRoomSessionFirebaseLoggerJob.perform_later(
    room_session_id: context.room_session.id,
    waiting_guest_firebase_doc_id: waiting_guest_firebase_doc_id
  )
end

#service_accountObject



83
84
85
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 83

def 
  Rails.application.credentials.
end

#with_session_creation_lockObject



38
39
40
41
42
43
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 38

def with_session_creation_lock
  SpreeCmCommissioner::WaitingRoomSession.transaction do
    SpreeCmCommissioner::WaitingRoomSession.connection.execute("SELECT pg_advisory_xact_lock(#{SESSION_CREATION_LOCK_KEY})")
    yield
  end
end