Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LTI-413: Reduce Actioncable jobs to improve performance #370

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion app/channels/meeting_info_channel.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ class MeetingInfoChannel < ApplicationCable::Channel
def subscribed
@chosen_room = Room.find(params[:room_id])
stream_for(@chosen_room)
NotifyMeetingWatcherJob.set(wait: 1.second).perform_later(@chosen_room, {})
end

def unsubscribed
Expand Down
12 changes: 4 additions & 8 deletions app/controllers/rooms_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def meeting_join

@meeting = join_meeting_url

broadcast_meeting(action: 'join', delay: true)
broadcast_meeting(action: 'join')
redirect_to(@meeting)
rescue BigBlueButton::BigBlueButtonException => e
logger.error(e.to_s)
Expand All @@ -169,18 +169,14 @@ def meeting_end
redirect_to(room_path(@room.id, launch_nonce: params['launch_nonce'])) # fallback if actioncable doesn't work
end

def broadcast_meeting(action: 'none', delay: false)
if delay
NotifyMeetingWatcherJob.set(wait: 5.seconds).perform_later(@chosen_room, action: action)
else
NotifyMeetingWatcherJob.perform_now(@chosen_room, action: action)
end
def broadcast_meeting(action: 'none')
RoomMeetingWatcherJob.set(wait: 5.seconds).perform_later(@chosen_room, action: action) unless @chosen_room.watcher_job_active
end

# GET /rooms/:id/meeting/close
def meeting_close
respond_to do |format|
broadcast_meeting(action: 'someone left', delay: true)
broadcast_meeting(action: 'someone left')
format.html { render(:autoclose) }
end
end
Expand Down
50 changes: 22 additions & 28 deletions app/javascript/packs/meetingInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,49 +20,43 @@ import '../channels/consumer'

$(document).on('turbolinks:load', function () {

var controller = $("body").data('controller');
var action = $("body").data('action');
var chosenRoomId = $("#body").data("chosenroomid");

if (!(controller == "rooms" && action == "meeting_join")) {
App.meetingInfo = App.cable.subscriptions.create({
channel: "MeetingInfoChannel",
room_id: chosenRoomId
}, {
connected: function () {
console.log("Connected to meeting info channel for [" + chosenRoomId + "]");
},
disconnected: function () {
console.log("Disconnected from meeting info channel");
},
received: function (data) {
console.log("Received data from meeting info channel. data: " + JSON.stringify(data));
if (data.meeting_in_progress == true) {
startTime = data.elapsed_time
start_elapsed_time();
display_participant_count(data.participant_count);
show_elems();
}
if (data.action == "end") {
hide_elements();
}
App.meetingInfo = App.cable.subscriptions.create({
channel: "MeetingInfoChannel",
room_id: chosenRoomId
}, {
connected: function () {
console.log("Connected to meeting info channel for [" + chosenRoomId + "]");
},
disconnected: function () {
console.log("Disconnected from meeting info channel");
},
received: function (data) {
console.log("Received data from meeting info channel. data: " + JSON.stringify(data));
if (data.meeting_in_progress == true) {
startTime = data.elapsed_time
start_elapsed_time();
display_participant_count(data.participant_count);
show_elems();
}
});
}
if (data.action == "end") {
hide_elements();
}
}
});
});

var startTime = 0;

var show_elems = function () {
$('#end-meeting-btn').show();
$('#meeting-info-msg').show();
$('#wait-for-mod-msg').hide();
}

var hide_elements = function () {
$('#end-meeting-btn').hide();
$('#meeting-info-msg').hide();
$('#wait-for-mod-msg').hide();
}

var display_participant_count = function (participantCount) {
Expand Down
48 changes: 0 additions & 48 deletions app/jobs/notify_meeting_watcher_job.rb

This file was deleted.

45 changes: 45 additions & 0 deletions app/jobs/room_meeting_watcher_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# frozen_string_literal: true

class RoomMeetingWatcherJob < ApplicationJob
queue_as :default
include BbbHelper

def perform(room, data)
return unless room

@chosen_room = room

info = fetch_meeting_info(data)
if info[:meeting_in_progress]
@chosen_room.update(watcher_job_active: true) unless @chosen_room.watcher_job_active # no need to update if it's already true

logger.info("Meeting in progress. Sending broadcast to room '#{room.name}'")
# Broadcast updates to this room’s channel
MeetingInfoChannel.broadcast_to(room, info)

# Re-enqueue to run again in 5 seconds
self.class.set(wait: 10.seconds).perform_later(room, info)
else
logger.info("Meeting is not in progress. Sending broadcast to room '#{room.name}'")

# Broadcast that the meeting ended
MeetingInfoChannel.broadcast_to(room, { meeting_in_progress: false, action: 'end' })
@chosen_room.update(watcher_job_active: false) if @chosen_room.watcher_job_active # no need to update if it's already false
# Do not re-enqueue, job ends here
end
end

private

def fetch_meeting_info(data)
info = meeting_info
data[:meeting_in_progress] = (info[:returncode] == 'SUCCESS' || info[:running] == true)
# Data for meeting not in progress.
(data[:action] = 'end') && (return data) unless data[:meeting_in_progress]

# Data for meeting in progress.
data[:elapsed_time] = info[:startTime]
data[:participant_count] = info[:participantCount]
data
end
end
11 changes: 11 additions & 0 deletions db/migrate/20241205194937_add_watcher_job_active_to_rooms.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true

class AddWatcherJobActiveToRooms < ActiveRecord::Migration[6.1]
def up
add_column(:rooms, :watcher_job_active, :boolean, default: false, null: false)
end

def down
remove_column(:rooms, :watcher_job_active)
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2024_11_20_203200) do
ActiveRecord::Schema.define(version: 2024_12_05_194937) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand All @@ -35,6 +35,7 @@
t.string "code"
t.string "shared_code"
t.boolean "use_shared_code"
t.boolean "watcher_job_active", default: false, null: false
t.index ["code"], name: "index_rooms_on_code"
t.index ["tenant", "code"], name: "index_rooms_on_tenant_and_code", unique: true
t.index ["tenant", "handler"], name: "index_rooms_on_tenant_and_handler", unique: true
Expand Down
2 changes: 1 addition & 1 deletion spec/controllers/rooms_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
},
},
})
allow_any_instance_of(NotifyMeetingWatcherJob).to(receive(:bbb).and_return(bbb_api)) # stub actioncable processes
allow_any_instance_of(RoomMeetingWatcherJob).to(receive(:bbb).and_return(bbb_api)) # stub actioncable processes
allow_any_instance_of(BrokerHelper).to(receive(:broker_tenant_info).and_return({
'handler_params' => 'context_id',
'hide_build_tag' => 'false',
Expand Down