FIX: Killing a Unicorn worker shouldn't kill a running backup or restore process

FIX: Killing a Unicorn worker shouldn’t kill a running backup or restore process

By spawning and forking the backup and restore, the process owner changes from :unicorn: to the init process.

diff --git a/lib/backup_restore.rb b/lib/backup_restore.rb
index 6528b17..b8a19ef 100644
--- a/lib/backup_restore.rb
+++ b/lib/backup_restore.rb
@@ -172,9 +172,9 @@ module BackupRestore
 
   def self.spawn_process!(type, user_id, opts)
     script = File.join(Rails.root, "script", "spawn_backup_restore.rb")
-    command = ["bundle", "exec", "ruby", script, type, user_id, opts.to_json].shelljoin
+    command = ["bundle", "exec", "ruby", script, type, user_id, opts.to_json].map(&:to_s)
 
-    pid = spawn({ "RAILS_DB" => RailsMultisite::ConnectionManagement.current_db }, command)
+    pid = spawn({ "RAILS_DB" => RailsMultisite::ConnectionManagement.current_db }, *command)
     Process.detach(pid)
   end
 
diff --git a/script/spawn_backup_restore.rb b/script/spawn_backup_restore.rb
index 57e0de5..4af4f66 100644
--- a/script/spawn_backup_restore.rb
+++ b/script/spawn_backup_restore.rb
@@ -1,38 +1,40 @@
 # frozen_string_literal: true
 # This script is used by BackupRestore.backup! and BackupRestore.restore!
 
-require File.expand_path("../../config/environment", __FILE__)
+fork do
+  require File.expand_path("../../config/environment", __FILE__)
 
-def backup
-  user_id, opts = parse_params
-  BackupRestore::Backuper.new(user_id, opts).run
-end
+  def backup
+    user_id, opts = parse_params
+    BackupRestore::Backuper.new(user_id, opts).run
+  end
 
-def restore
-  user_id, opts = parse_params
+  def restore
+    user_id, opts = parse_params
 
-  BackupRestore::Restorer.new(
-    user_id: user_id,
-    filename: opts[:filename],
-    factory: BackupRestore::Factory.new(
+    BackupRestore::Restorer.new(
       user_id: user_id,
-      client_id: opts[:client_id]
-    ),
-    disable_emails: opts.fetch(:disable_emails, true)
-  ).run
-end
+      filename: opts[:filename],
+      factory: BackupRestore::Factory.new(
+        user_id: user_id,
+        client_id: opts[:client_id]
+      ),
+      disable_emails: opts.fetch(:disable_emails, true)
+    ).run
+  end
 
-def parse_params
-  user_id = ARGV[1].to_i
-  opts = JSON.parse(ARGV[2], symbolize_names: true)
-  [user_id, opts]
-end
+  def parse_params
+    user_id = ARGV[1].to_i
+    opts = JSON.parse(ARGV[2], symbolize_names: true)
+    [user_id, opts]
+  end
 
-case ARGV[0]
-when "backup"
-  backup
-when "restore"
-  restore
-else
-  raise "Unknown argument: #{ARGV[0]}"
+  case ARGV[0]
+  when "backup"
+    backup
+  when "restore"
+    restore
+  else
+    raise "Unknown argument: #{ARGV[0]}"
+  end
 end

GitHub sha: 57095f0b

This commit appears in #10909 which was approved by eviltrout. It was merged by gschlager.