1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- class BackgroundServices
- def self.available_services
- BackgroundServices::Service.descendants
- end
- attr_reader :config
- def initialize(config)
- @config = Array(config)
- end
- def run
- Rails.logger.debug 'Starting BackgroundServices...'
- config.each do |service_config|
- run_service service_config
- end
- Process.waitall
- loop do
- sleep 1
- end
- rescue Interrupt
- nil
- ensure
- Rails.logger.debug('Stopping BackgroundServices.')
- end
- private
- def run_service(service_config)
- if !service_config.enabled?
- Rails.logger.debug { "Skipping disabled service #{service_config.service.service_name}." }
- return
- end
- service_config.service.pre_run
- case service_config.start_as
- when :fork
- start_as_forks(service_config.service, service_config.workers)
- when :thread
- start_as_thread(service_config.service)
- end
- end
- def start_as_forks(service, forks)
- (1..forks).map do
- Process.fork do
- Rails.logger.debug { "Starting process ##{Process.pid} for service #{service.service_name}." }
- service.new.run
- rescue Interrupt
- nil
- end
- end
- end
- def start_as_thread(service)
- Thread.new do
- Thread.current.abort_on_exception = true
- Rails.logger.debug { "Starting thread for service #{service.service_name} in the main process." }
- service.new.run
- # BackgroundServices rspec test is using Timeout.timeout to stop background services.
- # It was fine for a long time, but started throwing following error in Rails 7.2.
- # This seems to affect that test case only.
- # Unfortunately, since it's running on a separate thread, that error has to be rescued here.
- # That said, this should be handled by improving services loops to support graceful exiting.
- rescue ActiveRecord::ActiveRecordError => e
- raise e if Rails.env.test? && e.message != 'Cannot expire connection, it is not currently leased.' # rubocop:disable Zammad/DetectTranslatableString
- end
- end
- end
|