diff --git a/README.md b/README.md index 2404090c..ab2bc3b8 100644 --- a/README.md +++ b/README.md @@ -148,6 +148,10 @@ These variables are used by the service startup scripts in the Docker images, bu * `POLLER_THREADS`: The number of threads to run in the poller process. The default is 5. * `CONNECT_TIMEOUT`: The timeout for establishing a network connection to the BigBlueButton server in the load balancer and poller in seconds. Default is 5 seconds. Floating point numbers can be used for timeouts less than 1 second. * `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. The default is 15. +* `LOAD_JOIN_BUFFER_TIME`: The time until the `LOAD_MIN_USER_COUNT` will be used for calculating server load. The default is 15. +* `LOAD_MIN_WEBCAM_COUNT` : The minimum number of active webcams, used for calculating server load. The default is 1. +* `LOAD_SCREENSHARE_COUNT` : Disable counting 1 screenshare for calculating server load by setting this value as `false` ### Redis Connection (`config/redis_store.yml`) diff --git a/lib/tasks/poll.rake b/lib/tasks/poll.rake index e03aa612..aaeedaa9 100644 --- a/lib/tasks/poll.rake +++ b/lib/tasks/poll.rake @@ -38,19 +38,36 @@ namespace :poll do resp = get_post_req(encode_bbb_uri('getMeetings', server.url, server.secret)) meetings = resp.xpath('/response/meetings/meeting') + total_load = 0 + load_min_user_count = ENV.fetch('LOAD_MIN_USER_COUNT', '15').to_i + load_min_webcam_count = ENV.fetch('LOAD_MIN_WEBCAM_COUNT', '1').to_i + load_screenshare_count = ENV.fetch('LOAD_SCREENSHARE_COUNT', 'true') == 'true' ? 1 : 0 + x_minutes_ago = ENV.fetch('LOAD_JOIN_BUFFER_TIME', '15').to_i.minutes.ago + + 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 + actual_webcams = meeting.xpath('.//videoCount').text.to_i + total_load += if created_time > x_minutes_ago + [actual_attendees, load_min_user_count].max * (1 + 10 * actual_webcams + 20 * load_screenshare_count) + else + actual_attendees * (1 + 10 * load_min_webcam_count + 20 * load_screenshare_count) + end + end + # 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 = meetings.length * (server.load_multiplier.nil? ? 1.0 : server.load_multiplier.to_d) + server.load = total_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 = meetings.length * (server.load_multiplier.nil? ? 1.0 : server.load_multiplier.to_d) + server.load = total_load server.online = true end rescue StandardError => e