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 =
'waiting_room_session_creation'.freeze

Instance Method Summary collapse

Instance Method Details

#advisory_lock(lock_key) ⇒ Object



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

def advisory_lock(lock_key)
  lock_id = Zlib.crc32(lock_key)
  SpreeCmCommissioner::WaitingRoomSession.transaction do
    SpreeCmCommissioner::WaitingRoomSession.connection.execute("SELECT pg_advisory_xact_lock(#{lock_id})")
    yield
  end
end

#assign_token_and_create_session_to_dbObject



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

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



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

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.
  advisory_lock(SESSION_CREATION_LOCK_KEY) 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



72
73
74
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 72

def call_other_waiting_guests
  SpreeCmCommissioner::WaitingGuestsCallerJob.perform_later
end

#expired_atObject



76
77
78
79
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 76

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



81
82
83
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 81

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

#full?Boolean

Returns:

  • (Boolean)


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

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



47
48
49
50
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 47

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



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

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



85
86
87
# File 'app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb', line 85

def 
  Rails.application.credentials.
end