-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
close #1991 add virtual waiting room
- Loading branch information
Showing
19 changed files
with
373 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
app/controllers/concerns/spree_cm_commissioner/waiting_room_authorization.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
module SpreeCmCommissioner | ||
module WaitingRoomAuthorization | ||
extend ActiveSupport::Concern | ||
|
||
included do | ||
rescue_from JWT::ExpiredSignature, with: :handle_waiting_room_session_token_error | ||
rescue_from JWT::VerificationError, with: :handle_waiting_room_session_token_error | ||
rescue_from JWT::DecodeError, with: :handle_waiting_room_session_token_error | ||
|
||
before_action :ensure_waiting_room_session_token | ||
end | ||
|
||
def ensure_waiting_room_session_token | ||
return if disabled_authorization? | ||
|
||
JWT.decode(params[:waiting_room_session_token], ENV.fetch('WAITING_ROOM_SIGNATURE'), true, { algorithm: 'HS256' }) | ||
end | ||
|
||
def disabled_authorization? | ||
ENV['DISABLE_WAITING_ROOM_AUTHORIZATION'] == 'yes' | ||
end | ||
|
||
def handle_waiting_room_session_token_error | ||
render_error_payload(exception.message, 400) | ||
end | ||
end | ||
end |
23 changes: 23 additions & 0 deletions
23
app/controllers/spree/api/v2/storefront/waiting_room_sessions_controller.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# We use lambda instead of following API to generate token. Following are just sample. | ||
# | ||
# POST: /api/v2/storefront/waiting_room_sesions | ||
# Response: { token: token } | ||
module Spree | ||
module Api | ||
module V2 | ||
module Storefront | ||
class WaitingRoomSessionsController < ::Spree::Api::V2::ResourceController | ||
skip_before_action :ensure_waiting_room_session_token | ||
|
||
def create | ||
context = SpreeCmCommissioner::WaitingRoomSessionCreator.call( | ||
ip: request.ip, | ||
firebase_document_id: params[:firebase_document_id] | ||
) | ||
render json: { token: context.token } | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
32 changes: 32 additions & 0 deletions
32
app/interactors/spree_cm_commissioner/server_instances_bulk_creator.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
require 'aws-sdk-ecs' | ||
|
||
module SpreeCmCommissioner | ||
class ServerInstancesBulkCreator < BaseInteractor | ||
def call | ||
ecs_client = Aws::ECS::Client.new( | ||
region: ENV.fetch('AWS_REGION'), | ||
access_key_id: ENV.fetch('AWS_ACCESS_KEY_ID'), | ||
secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY') | ||
) | ||
|
||
tasks_response = ecs_client.list_tasks( | ||
cluster: ENV.fetch('AWS_CLUSTER_NAME'), | ||
launch_type: 'FARGATE' | ||
) | ||
|
||
context.servers = [] | ||
context.task_arns = tasks_response.task_arns | ||
context.task_arns.each do |task_arn| | ||
server = SpreeCmCommissioner::ServerInstance.where(instance_id: task_arn).first_or_initialize | ||
server.concurrent_requests ||= 5 | ||
server.status = :active | ||
server.save! if server.changed? | ||
context.servers << server | ||
end | ||
|
||
SpreeCmCommissioner::ServerInstance.where.not(id: context.servers.pluck(:id)).find_each do |server| | ||
server.update!(status: :inactive) | ||
end | ||
end | ||
end | ||
end |
44 changes: 44 additions & 0 deletions
44
app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
require 'google/cloud/firestore' | ||
|
||
module SpreeCmCommissioner | ||
class WaitingRoomSessionCreator < BaseInteractor | ||
delegate :ip, :firebase_document_id, to: :context | ||
|
||
def call | ||
return context.fail!(message: 'must_provide_firebase_document_id') if firebase_document_id.blank? | ||
return context.fail!(message: 'must_provide_ip') if ip.blank? | ||
|
||
generate_jwt_token | ||
assign_token_and_create_session_to_db | ||
log_to_firebase | ||
end | ||
|
||
def generate_jwt_token | ||
payload = { exp: expired_at.to_i } | ||
context.jwt_token = JWT.encode(payload, ENV.fetch('WAITING_ROOM_SIGNATURE'), 'HS256') | ||
end | ||
|
||
def assign_token_and_create_session_to_db | ||
context.room_sesion = SpreeCmCommissioner::WaitingRoomSession.create!(token: context.jwt_token, expired_at: expired_at, ip: ip) | ||
end | ||
|
||
def log_to_firebase | ||
firestore = Google::Cloud::Firestore.new(project_id: service_account[:project_id], credentials: service_account) | ||
document = firestore.col('waiting_guests').doc(firebase_document_id) | ||
|
||
data = document.get.data.dup | ||
data[:entered_room_at] = Time.zone.now | ||
|
||
document.update(data) | ||
end | ||
|
||
def expired_at | ||
expired_duration = ENV['WAITING_ROOM_SESSION_EXPIRE_DURATION_IN_SECOND']&.presence&.to_i || (60 * 5) | ||
context.expired_at ||= expired_duration.seconds.from_now | ||
end | ||
|
||
def service_account | ||
Rails.application.credentials.cloud_firestore_service_account | ||
end | ||
end | ||
end |
33 changes: 33 additions & 0 deletions
33
app/interactors/spree_cm_commissioner/waiting_room_sessions_releaser.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
require 'google/cloud/firestore' | ||
|
||
module SpreeCmCommissioner | ||
class WaitingRoomSessionsReleaser < BaseInteractor | ||
def call | ||
context.max_sessions = SpreeCmCommissioner::ServerInstance.max_sessions | ||
context.active_sessions = SpreeCmCommissioner::WaitingRoomSession.active.count | ||
|
||
available_slots = context.max_sessions - context.active_sessions | ||
waiting_guests = query(available_slots) | ||
|
||
waiting_guests.each do |document| | ||
data = document.get.data.dup | ||
data[:allow_to_refresh_to_enter_room_at] = Time.utc.now | ||
document.update(data) | ||
end | ||
end | ||
|
||
# This query required index. create them in Firebase beforehand. | ||
def query(available_slots) | ||
firestore = Google::Cloud::Firestore.new(project_id: service_account[:project_id], credentials: service_account) | ||
firestore.col('waiting_guests') | ||
.where('allow_to_refresh_to_enter_room_at', '==', nil) | ||
.order('queued_at') | ||
.limit(available_slots) | ||
.get | ||
end | ||
|
||
def service_account | ||
Rails.application.credentials.cloud_firestore_service_account | ||
end | ||
end | ||
end |
10 changes: 10 additions & 0 deletions
10
app/jobs/spree_cm_commissioner/server_instances_bulk_creator_job.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# server_instances_bulk_creator: | ||
# cron: cron: "*/30 * * * *" # Every 30 minute | ||
# class: SpreeCmCommissioner::ServerInstanceBulkCreatorJob | ||
module SpreeCmCommissioner | ||
class ServerInstancesBulkCreatorJob < ApplicationJob | ||
def perform | ||
SpreeCmCommissioner::ServerInstancesBulkCreator.call | ||
end | ||
end | ||
end |
10 changes: 10 additions & 0 deletions
10
app/jobs/spree_cm_commissioner/waiting_room_sessions_releaser_job.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# waiting_room_sessions_releaser: | ||
# cron: cron: "*/1 * * * *" # Every minute | ||
# class: SpreeCmCommissioner::WaitingRoomSessionsReleaserJob | ||
module SpreeCmCommissioner | ||
class WaitingRoomSessionsReleaserJob < ApplicationJob | ||
def perform | ||
SpreeCmCommissioner::WaitingRoomSessionsReleaser.call | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module SpreeCmCommissioner | ||
class ServerInstance < Base | ||
validates :instance_id, presence: true | ||
validates :concurrent_requests, presence: true | ||
|
||
enum status: { active: 0, inactive: 1 } | ||
|
||
def max_sessions | ||
ServerInstance.active.select('SUM(concurrent_requests * multiply_by) AS total').take.total | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
module SpreeCmCommissioner | ||
class WaitingRoomSession < Base | ||
validates :token, presence: true | ||
validates :expired_at, presence: true | ||
validates :ip, presence: true | ||
|
||
scope :active, -> { SpreeCmCommissioner::WaitingRoomSession.where('expired_at > ?', Time.current) } | ||
|
||
def expired? | ||
expired_at < Time.current | ||
end | ||
end | ||
end |
14 changes: 14 additions & 0 deletions
14
db/migrate/20241119032456_create_cm_waiting_room_sessions.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
class CreateCmWaitingRoomSessions < ActiveRecord::Migration[7.0] | ||
def change | ||
create_table :cm_waiting_room_sessions, if_not_exists: true do |t| | ||
t.string :token, null: false | ||
t.string :ip, null: false | ||
t.datetime :expired_at, null: false | ||
|
||
t.timestamps | ||
end | ||
|
||
add_index :cm_waiting_room_sessions, :expired_at, if_not_exists: true | ||
add_index :cm_waiting_room_sessions, :token, if_not_exists: true | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
class CreateCmServerInstances < ActiveRecord::Migration[7.0] | ||
def change | ||
create_table :cm_server_instances, if_not_exists: true do |t| | ||
t.string :instance_id, null: false | ||
t.integer :concurrent_requests, default: 5, null: false | ||
t.integer :multiply_by, default: 1, null: false | ||
t.integer :status, default: 0, null: false | ||
|
||
t.timestamps | ||
end | ||
|
||
add_index :cm_server_instances, :instance_id, if_not_exists: true | ||
add_index :cm_server_instances, :status, if_not_exists: true | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# recommend to be used in schedule.yml & manually access in /sidekiq/cron | ||
namespace :spree_cm_commissioner do | ||
desc 'Create services instances by fetch from AWS' | ||
task server_instances_bulk_creator: :environment do | ||
ServerInstancesBulkCreatorJob.perform_now | ||
end | ||
end |
52 changes: 52 additions & 0 deletions
52
...tancesBulkCreator/_call/request_all_tasks_create_active_servers_inactive_all_services.yml
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Oops, something went wrong.