Browse Source

Performance: Parallelize Session.jobs if ENV 'ZAMMAD_SESSION_JOBS_CONCURRENT' is provided with number of dedicated worker node processes to spawn.

Thorsten Eckel 5 years ago
parent
commit
1aeb0a9ba5
3 changed files with 42 additions and 4 deletions
  1. 1 1
      .rubocop_todo.yml
  2. 32 2
      lib/sessions.rb
  3. 9 1
      script/scheduler.rb

+ 1 - 1
.rubocop_todo.yml

@@ -42,7 +42,7 @@ Metrics/CyclomaticComplexity:
 # Offense count: 27
 # Configuration parameters: CountComments.
 Metrics/ModuleLength:
-  Max: 559
+  Max: 578
 
 # Offense count: 274
 Metrics/PerceivedComplexity:

+ 32 - 2
lib/sessions.rb

@@ -616,11 +616,41 @@ delete spool messages
 
     # just make sure that spool path exists
     if !File.exist?(@path)
-      FileUtils.mkpath @path
+      FileUtils.mkpath(@path)
     end
 
     # dispatch sessions
-    if node_id&.zero?
+    if node_id.blank? && ENV['ZAMMAD_SESSION_JOBS_CONCURRENT'].to_i.positive?
+
+      dispatcher_pid = Process.pid
+      node_count     = ENV['ZAMMAD_SESSION_JOBS_CONCURRENT'].to_i
+      node_pids      = []
+      (1..node_count).each do |worker_node_id|
+        node_pids << fork do
+          title         = "Zammad Session Jobs Node ##{worker_node_id}: dispatch_pid:#{dispatcher_pid} -> worker_pid:#{Process.pid}"
+          $PROGRAM_NAME = title
+
+          log('info', "#{title} started.")
+
+          ::Sessions.jobs(worker_node_id)
+          sleep node_count
+        rescue Interrupt # rubocop:disable Layout/RescueEnsureAlignment
+          nil
+        end
+      end
+
+      Signal.trap 'SIGTERM' do
+
+        node_pids.each do |node_pid|
+          Process.kill 'TERM', node_pid
+        end
+
+        Process.waitall
+
+        raise SignalException, 'SIGTERM'
+      end
+
+      # displatch client_ids to nodes
       loop do
 
         # nodes

+ 9 - 1
script/scheduler.rb

@@ -59,7 +59,15 @@ Daemons.run_proc('scheduler', daemon_options) do
 
   Rails.logger.info 'Scheduler started.'
   at_exit do
-    Rails.logger.info 'Scheduler stopped.'
+
+    # use process title for stop log entry
+    # if differs from default process title
+    title = 'Scheduler'
+    if $PROGRAM_NAME != 'scheduler.rb'
+      title = $PROGRAM_NAME
+    end
+
+    Rails.logger.info "#{title} stopped."
   end
 
   begin