This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/lib/backup_restore_v2/operation.rb
2023-01-13 00:20:33 +01:00

81 lines
2.0 KiB
Ruby

# frozen_string_literal: true
module BackupRestoreV2
class OperationRunningError < RuntimeError
end
class Operation
RUNNING_KEY = "backup_restore_operation_is_running"
ABORT_KEY = "backup_restore_operation_should_shutdown"
def self.start
if !Discourse.redis.set(RUNNING_KEY, "1", ex: 60, nx: true)
raise BackupRestoreV2::OperationRunningError
end
@keep_running_thread = keep_running
@abort_listener_thread = listen_for_abort_signal
Rails.env.test? ? [@keep_running_thread, @abort_listener_thread] : true
end
def self.finish
if @keep_running_thread
@keep_running_thread.kill
@keep_running_thread.join if @keep_running_thread.alive?
@keep_running_thread = nil
end
Discourse.redis.del(RUNNING_KEY)
if @abort_listener_thread
@abort_listener_thread.join if @abort_listener_thread.alive?
@abort_listener_thread = nil
end
end
def self.running?
!!Discourse.redis.get(RUNNING_KEY)
end
def self.abort!
Discourse.redis.set(ABORT_KEY, "1")
end
def self.should_abort?
!!Discourse.redis.get(ABORT_KEY)
end
private_class_method def self.keep_running
start_thread("keep_running") do
while true
# extend the expiry by 1 minute every 30 seconds
Discourse.redis.expire(RUNNING_KEY, 60.seconds)
sleep(30.seconds)
end
end
end
private_class_method def self.listen_for_abort_signal
Discourse.redis.del(ABORT_KEY)
start_thread("abort_listener") do
while running?
exit if should_abort?
sleep(0.1)
end
end
end
private_class_method def self.start_thread(name)
db = RailsMultisite::ConnectionManagement.current_db
Thread.new do
RailsMultisite::ConnectionManagement.with_connection(db) do
Thread.current.name = name
yield
end
end
end
end
end