Class: Belated

Inherits:
Object
  • Object
show all
Extended by:
Dry::Configurable
Includes:
Logging, Singleton
Defined in:
lib/belated.rb,
lib/belated/queue.rb,
lib/belated/client.rb,
lib/belated/engine.rb,
lib/belated/worker.rb,
lib/belated/logging.rb,
lib/belated/testing.rb,
lib/belated/testing.rb,
lib/belated/version.rb,
lib/belated/exceptions.rb,
lib/belated/job_wrapper.rb,
app/controllers/belated/admin_controller.rb

Overview

Belated is a pure Ruby job backend. It has limited functionality, as it only accepts jobs as procs, but that might make it useful if you don’t need anything as big as Redis. Saves jobs into a file as YAML as long as they’re not procs and reloads them when started again.

Defined Under Namespace

Modules: Logging Classes: AdminController, Client, Engine, JobError, JobWrapper, Queue, Testing, Worker

Constant Summary collapse

URI =
"druby://#{Belated.host}:#{Belated.port}"
VERSION =
'0.9.0'
@@queue =
Belated::Queue.new

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logging

#error, #log, #logger, #logger=, #warn

Class Method Details

.all_future_jobsObject



165
166
167
# File 'lib/belated.rb', line 165

def all_future_jobs
  @@queue.future_jobs
end

.clear_queue!Object



169
170
171
# File 'lib/belated.rb', line 169

def clear_queue!
  @@queue.clear
end

.delete(job_id) ⇒ Object



153
154
155
156
# File 'lib/belated.rb', line 153

def delete(job_id)
  job = find(job_id)
  @@queue.delete_job(job)
end

.fetch_jobObject



173
174
175
# File 'lib/belated.rb', line 173

def fetch_job
  @@queue.pop
end

.find(job_id) ⇒ Object



149
150
151
# File 'lib/belated.rb', line 149

def find(job_id)
  @@queue.find(job_id)
end

.job_listObject



182
183
184
# File 'lib/belated.rb', line 182

def self.job_list
  @@queue
end

.kill_and_clear_queue!Object



158
159
160
161
162
163
# File 'lib/belated.rb', line 158

def kill_and_clear_queue!
  @worker_list&.each do |worker|
    Thread.kill(worker)
  end
  clear_queue!
end

Instance Method Details



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/belated.rb', line 118

def banner
  <<-'BANNER'

  .----------------. .----------------. .----------------. .----------------. .----------------. .----------------. .----------------.
  | .--------------. | .--------------. | .--------------. | .--------------. | .--------------. | .--------------. | .--------------. |
  | |   ______     | | |  _________   | | |   _____      | | |      __      | | |  _________   | | |  _________   | | |  ________    | |
  | |  |_   _ \    | | | |_   ___  |  | | |  |_   _|     | | |     /  \     | | | |  _   _  |  | | | |_   ___  |  | | | |_   ___ `.  | |
  | |    | |_) |   | | |   | |_  \_|  | | |    | |       | | |    / /\ \    | | | |_/ | | \_|  | | |   | |_  \_|  | | |   | |   `. \ | |
  | |    |  __'.   | | |   |  _|  _   | | |    | |   _   | | |   / ____ \   | | |     | |      | | |   |  _|  _   | | |   | |    | | | |
  | |   _| |__) |  | | |  _| |___/ |  | | |   _| |__/ |  | | | _/ /    \ \_ | | |    _| |_     | | |  _| |___/ |  | | |  _| |___.' / | |
  | |  |_______/   | | | |_________|  | | |  |________|  | | ||____|  |____|| | |   |_____|    | | | |_________|  | | | |________.'  | |
  | |              | | |              | | |              | | |              | | |              | | |              | | |              | |
  | '--------------' | '--------------' | '--------------' | '--------------' | '--------------' | '--------------' | '--------------' |
   '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------'
  BANNER
end


135
136
137
138
139
# File 'lib/belated.rb', line 135

def banner_and_info
  log banner
  log "Currently running Belated version #{Belated::VERSION} in #{Belated.env}"
  log %(Belated running #{@worker_list&.length.to_i} workers on #{URI}...)
end

#boot_appObject



90
91
92
93
94
95
96
97
# File 'lib/belated.rb', line 90

def boot_app
  return unless rails?

  ENV['RAILS_ENV'] ||= Belated.env
  require File.expand_path("#{Belated.config.rails_path}/config/environment.rb")
  require 'rails/all'
  require 'active_job/queue_adapters/belated_adapter'
end

#connect!Object

Handles connection to DRb server.



65
66
67
68
69
70
71
# File 'lib/belated.rb', line 65

def connect!
  i = 0
  DRb.start_service(URI, @@queue, verbose: true)
rescue DRb::DRbConnError, Errno::EADDRINUSE
  sleep 0.1 and retry if (i += 1) < 5
  error 'Could not connect to DRb server.'
end

#job_listObject



178
179
180
# File 'lib/belated.rb', line 178

def job_list
  @@queue
end

#rails?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/belated.rb', line 99

def rails?
  Belated.config.rails
end

#reloadObject



103
104
105
106
# File 'lib/belated.rb', line 103

def reload
  log 'reloading...'
  @@queue.load_jobs
end

#startObject Also known as: initialize

Since it’s running as a singleton, we need something to start it up. Aliased for testing purposes. This is only run from the bin file.



49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/belated.rb', line 49

def start
  boot_app && @@queue.load_jobs
  @worker_list = []
  Belated.config.workers.times do |i|
    @worker_list << Thread.new { Worker.new(number: i.next) }
  end
  return unless Belated.config.connect

  connect!
  banner_and_info
  trap_signals
  @@queue.enqueue_future_jobs
end

#statsObject



141
142
143
144
145
146
# File 'lib/belated.rb', line 141

def stats
  {
    jobs: @@queue.size,
    workers: @worker_list&.length
  }
end

#stop_workersObject



108
109
110
111
112
113
114
115
116
# File 'lib/belated.rb', line 108

def stop_workers
  @worker_list&.each do |worker|
    i = 0
    sleep 0.1 while worker.alive? || (i + 0.1) < 10
    Thread.kill(worker)
  end
  @@queue.save_jobs
  exit unless $TESTING
end

#trap_signalsObject



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/belated.rb', line 73

def trap_signals
  %w[INT TERM].each do |signal|
    Signal.trap(signal) do
      @worker_list.length.times do
        @@queue.push(:shutdown)
      end
      Thread.new { stop_workers }
      # Max 40 seconds to shutdown
      timeout = 0
      until (timeout += 0.1) >= 40 || @@queue.empty? || $TESTING
        sleep 0.1
      end
      exit
    end
  end
end