From 8098b6b3ad20787579264273db251e24b41cb63d Mon Sep 17 00:00:00 2001
From: Calvin Walton <calvin.walton@kepstin.ca>
Date: Wed, 28 Apr 2021 15:53:20 -0400
Subject: [PATCH] Recording: Halt processing after archive step for
 non-recorded meetings

In the case where a meeting had recording enabled (record=true on create
call) but the presenter did not start recording during the meeting,
recording processing needs to be stopped after the meeting data is
archived, but before the recording formats are processed.

In the current 2.3 code, processing is halted after the "sanity" step.
However, the 2.2 code stopped processing after the "archive" step
instead. The main difference is that the scripts in the "post_archive"
directory (which are actually post_sanity scripts) did not get run on
non-recorded meetings for 2.2. This behaviour should be preserved for
compatibility.

I have added a special exception to trigger halting processing for a
recording job without causing the entire resque job to be marked as
failed. It only causes the `schedule_next_step` method to be skipped, so
following jobs won't get automatically run. This fixes #11877
---
 .../recordandplayback/workers/archive_worker.rb    |  7 ++++---
 .../lib/recordandplayback/workers/base_worker.rb   | 14 ++++++++++++++
 .../lib/recordandplayback/workers/sanity_worker.rb |  6 +-----
 3 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/record-and-playback/core/lib/recordandplayback/workers/archive_worker.rb b/record-and-playback/core/lib/recordandplayback/workers/archive_worker.rb
index 3a58c6696f..aac40629ec 100755
--- a/record-and-playback/core/lib/recordandplayback/workers/archive_worker.rb
+++ b/record-and-playback/core/lib/recordandplayback/workers/archive_worker.rb
@@ -42,9 +42,8 @@ module BigBlueButton
             !File.exist?(@archived_fail)
           )
 
-          if File.exist?(@archived_norecord)
-            @publisher.put_archive_norecord(@meeting_id)
-          end
+          norecord = File.exist?(@archived_norecord)
+          @publisher.put_archive_norecord(@meeting_id) if norecord
 
           @publisher.put_archive_ended(@meeting_id, success: step_succeeded, step_time: step_time)
 
@@ -56,6 +55,8 @@ module BigBlueButton
           end
           @logger.debug("Finished archive worker for #{@full_id}")
 
+          raise WorkerNoRecordHalt, "Meeting #{@full_id} had no recording marks" if norecord
+
           step_succeeded
         end
       end
diff --git a/record-and-playback/core/lib/recordandplayback/workers/base_worker.rb b/record-and-playback/core/lib/recordandplayback/workers/base_worker.rb
index 5d9159afa8..9b6901c1ef 100644
--- a/record-and-playback/core/lib/recordandplayback/workers/base_worker.rb
+++ b/record-and-playback/core/lib/recordandplayback/workers/base_worker.rb
@@ -25,6 +25,17 @@ require 'resque'
 
 module BigBlueButton
   module Resque
+    # Base class of exceptions specific to the worker/queue system
+    class WorkerError < StandardError; end
+
+    # Exceptions that should prevent the queue system from executing the next job, but which are not actually
+    # errors.
+    class WorkerHalt < WorkerError; end
+
+    # A meeting had recording enabled (record=true) but did not have recording marks and should not be automatically
+    # processed.
+    class WorkerNoRecordHalt < WorkerHalt; end
+
     class BaseWorker
       @queue = 'rap:base'
 
@@ -45,6 +56,9 @@ module BigBlueButton
         raise "Worker #{@step_name} for #{@meeting_id} failed with result #{success}" unless success
 
         schedule_next_step unless @single_step
+      rescue WorkerHalt => e
+        @logger.info(e.message)
+        @logger.info("Ended worker #{@step_name} for #{@meeting_id} with worker halt. Following steps will not be run.")
       rescue StandardError => e
         @logger.error(e.message)
         e.backtrace.each do |traceline|
diff --git a/record-and-playback/core/lib/recordandplayback/workers/sanity_worker.rb b/record-and-playback/core/lib/recordandplayback/workers/sanity_worker.rb
index 16e7e5874c..b5cdf533bb 100755
--- a/record-and-playback/core/lib/recordandplayback/workers/sanity_worker.rb
+++ b/record-and-playback/core/lib/recordandplayback/workers/sanity_worker.rb
@@ -47,10 +47,7 @@ module BigBlueButton
             FileUtils.touch(@sanity_fail)
           end
 
-          # Avoid the regular process flow if it's a norecord meeting
-          process = !File.exist?(@archived_norecord)
-
-          step_succeeded && process
+          step_succeeded
         end
       end
 
@@ -63,7 +60,6 @@ module BigBlueButton
         super(opts)
         @step_name = 'sanity'
         @post_scripts_path = File.join(BigBlueButton.rap_scripts_path, 'post_archive')
-        @archived_norecord = "#{@recording_dir}/status/archived/#{@full_id}.norecord"
         @sanity_fail = "#{@recording_dir}/status/sanity/#{@full_id}.fail"
         @sanity_done = "#{@recording_dir}/status/sanity/#{@full_id}.done"
       end
-- 
GitLab