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

make @defnull's proposition into a PR #476

Closed
Closed
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
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,14 @@ These variables are used by the service startup scripts in the Docker images, bu
* `RESPONSE_TIMEOUT`: The timeout to wait for a response after sending a request to the BigBlueButton server in the load balancer and poller in seconds. Default is 10 seconds. Floating point numbers can be used for timeouts less than 1 second.
* `LOAD_MIN_USER_COUNT`: Minimum user count of a meeting, used for calculating server load. Defaults to 15.
* `LOAD_JOIN_BUFFER_TIME`: The time(in minutes) until the `LOAD_MIN_USER_COUNT` will be used for calculating server load. Defaults to 15.
* `LOAD_WEIGHT_MEETINGS`: The weight the number of meetings will have in calculating server load
* `LOAD_WEIGHT_USERS`: The weight the number of users will have in calculating server load
* `LOAD_WEIGHT_AUDIO`: The weight the number of audio-streams will have in calculating server load. Alternatively explicitly specify weight for rx and tx, see below.
* `LOAD_WEIGHT_VIDEO`: The weight the number of video-streams will have in calculating server load. Alternatively explicitly specify weight for rx and tx, see below.
* `LOAD_WEIGHT_AUDIO_RX`: The weight the number of received audio-streams will have in calculating server load. For more fine-grained control.
* `LOAD_WEIGHT_AUDIO_TX`: The weight the number of sent audio-streams will have in calculating server load. For more fine-grained control.
* `LOAD_WEIGHT_VIDEO_RX`: The weight the number of received video-streams will have in calculating server load. For more fine-grained control.
* `LOAD_WEIGHT_VIDEO_TX`: The weight the number of sent video-streams will have in calculating server load. For more fine-grained control.
* `SERVER_ID_IS_HOSTNAME`: If set to "true", then instead of generating random UUIDs as the server ID when adding a server Scalelite will use the hostname of the server as the id. Server hostnames will be checked for uniqueness. Defaults to "false".
* `CREATE_EXCLUDE_PARAMS`: List of BBB server attributes that should not be modified by create API call. Should be in the format 'CREATE_EXCLUDE_PARAMS=param1,param2,param3'.
* `JOIN_EXCLUDE_PARAMS`: List of BBB server attributes that should not be modified by join API call. Should be in the format 'JOIN_EXCLUDE_PARAMS=param1,param2,param3'.
Expand Down
18 changes: 18 additions & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,24 @@ class Application < Rails::Application
# Whether to generate ids for servers based on the hostname rather than random UUIDs. Default to false.
config.x.server_id_is_hostname = ENV.fetch('SERVER_ID_IS_HOSTNAME', 'false').casecmp?('true')

# The weight the number of meetings will have in calculating server load
config.x.weight_meetings = ENV.fetch('LOAD_WEIGHT_MEETINGS', 1.0).to_d

# The weight the number of users will have in calculating server load
config.x.weight_users = ENV.fetch('LOAD_WEIGHT_USERS', 0).to_d

# The weight the number of audio-rx-streams will have in calculating server load. Can use same weight for both.
config.x.weight_audio_rx = (ENV.fetch('LOAD_WEIGHT_AUDIO_RX') { ENV.fetch('LOAD_WEIGHT_AUDIO', 0) }).to_d

# The weight the number of audio-tx-streams will have in calculating server load. Can use same weight for both.
config.x.weight_audio_tx = (ENV.fetch('LOAD_WEIGHT_AUDIO_TX') { ENV.fetch('LOAD_WEIGHT_AUDIO', 0) }).to_d

# The weight the number of video-rx-streams will have in calculating server load. Can use same weight for both.
config.x.weight_video_rx = (ENV.fetch('LOAD_WEIGHT_VIDEO_RX') { ENV.fetch('LOAD_WEIGHT_VIDEO', 0) }).to_d

# The weight the number of video-tx-streams will have in calculating server load. Can use same weight for both.
config.x.weight_video_tx = (ENV.fetch('LOAD_WEIGHT_VIDEO_TX') { ENV.fetch('LOAD_WEIGHT_VIDEO', 0) }).to_d

# Recording feature will be disabled, if set to 'true'. Defaults to false.
config.x.recording_disabled = ENV.fetch('RECORDING_DISABLED', 'false').casecmp?('true')
# List of BBB server attributes that should not be modified by create API call
Expand Down
36 changes: 28 additions & 8 deletions lib/tasks/poll.rake
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,14 @@ namespace :poll do

load_min_user_count = Rails.configuration.x.load_min_user_count
x_minutes_ago = Rails.configuration.x.load_join_buffer_time.ago

weight_meetings = Rails.configuration.x.weight_meetings
weight_users = Rails.configuration.x.weight_users
weight_audio_rx = Rails.configuration.x.weight_audio_rx
weight_audio_tx = Rails.configuration.x.weight_audio_tx
weight_video_rx = Rails.configuration.x.weight_video_rx
weight_video_tx = Rails.configuration.x.weight_video_tx

load = 0.0
meetings.each do |meeting|
created_time = Time.zone.at(meeting.xpath('.//createTime').text.to_i / 1000)
actual_attendees = meeting.xpath('.//participantCount').text.to_i + meeting.xpath('.//moderatorCount').text.to_i
Expand All @@ -58,25 +65,38 @@ namespace :poll do

next if meeting.xpath('.//isBreakout').text.eql?('true')

total_attendees += if created_time > x_minutes_ago
[actual_attendees, load_min_user_count].max
else
actual_attendees
end
attendees = if created_time > x_minutes_ago
[actual_attendees, load_min_user_count].max
else
actual_attendees
end
audio = meeting.at('voiceParticipantCount')&.content.to_i
video = meeting.at('videoCount')&.content.to_i
load += weight_meetings * 1
# Account for users in main rooms only - they join two rooms at the same time.
load += weight_users * attendees if meeting.xpath('.//isBreakout').text.eql?('false')
# Audio is mixed server-side -> Only one downstream per user
load += weight_audio_rx * audio
load += weight_audio_tx * attendees if audio
# Video is NOT mixed server-side -> One downstream per user per video
load += weight_video_rx * video
load += weight_video_tx * attendees * video
end
load *= server.load_multiplier.nil? ? 1.0 : server.load_multiplier.to_d

# Reset unhealthy counter so that only consecutive unhealthy calls are counted
server.reset_unhealthy_counter

if server.online
# Update the load if the server is currently online
server.load = total_attendees * (server.load_multiplier.nil? ? 1.0 : server.load_multiplier.to_d)
server.load = load
else
# Only bring the server online if the number of successful requests is >= the acceptable threshold
next if server.increment_healthy < Rails.configuration.x.server_healthy_threshold

Rails.logger.info("Server id=#{server.id} is healthy. Bringing back online...")
server.reset_counters
server.load = total_attendees * (server.load_multiplier.nil? ? 1.0 : server.load_multiplier.to_d)
server.load = load
server.online = true
end

Expand Down