background_services.rb 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class BackgroundServices
  3. def self.available_services
  4. BackgroundServices::Service.descendants
  5. end
  6. attr_reader :config
  7. def initialize(config)
  8. @config = Array(config)
  9. end
  10. def run
  11. Rails.logger.debug 'Starting BackgroundServices...'
  12. # Fork before starting the threads in the main process to ensure a consistent state
  13. # and minimal memory overhead (see also #5420).
  14. config
  15. .in_order_of(:start_as, %i[fork thread])
  16. .each do |service_config|
  17. run_service service_config
  18. end
  19. Process.waitall
  20. loop do
  21. sleep 1
  22. end
  23. rescue Interrupt
  24. nil
  25. ensure
  26. Rails.logger.debug('Stopping BackgroundServices.')
  27. end
  28. private
  29. def run_service(service_config)
  30. if !service_config.enabled?
  31. Rails.logger.debug { "Skipping disabled service #{service_config.service.service_name}." }
  32. return
  33. end
  34. service_config.service.pre_run
  35. case service_config.start_as
  36. when :fork
  37. start_as_forks(service_config.service, service_config.workers)
  38. when :thread
  39. start_as_thread(service_config.service)
  40. end
  41. end
  42. def start_as_forks(service, forks)
  43. (1..forks).map do
  44. Process.fork do
  45. Rails.logger.debug { "Starting process ##{Process.pid} for service #{service.service_name}." }
  46. service.new.run
  47. rescue Interrupt
  48. nil
  49. end
  50. end
  51. end
  52. def start_as_thread(service)
  53. Thread.new do
  54. Thread.current.abort_on_exception = true
  55. Rails.logger.debug { "Starting thread for service #{service.service_name} in the main process." }
  56. service.new.run
  57. end
  58. end
  59. end