exekutor 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -3
- data/exe/exekutor +2 -2
- data/lib/active_job/queue_adapters/exekutor_adapter.rb +2 -1
- data/lib/exekutor/asynchronous.rb +143 -75
- data/lib/exekutor/cleanup.rb +27 -28
- data/lib/exekutor/configuration.rb +102 -48
- data/lib/exekutor/hook.rb +15 -11
- data/lib/exekutor/info/worker.rb +3 -3
- data/lib/exekutor/internal/base_record.rb +2 -1
- data/lib/exekutor/internal/callbacks.rb +55 -35
- data/lib/exekutor/internal/cli/app.rb +33 -23
- data/lib/exekutor/internal/cli/application_loader.rb +17 -6
- data/lib/exekutor/internal/cli/cleanup.rb +54 -40
- data/lib/exekutor/internal/cli/daemon.rb +9 -11
- data/lib/exekutor/internal/cli/default_option_value.rb +3 -1
- data/lib/exekutor/internal/cli/info.rb +117 -84
- data/lib/exekutor/internal/cli/manager.rb +234 -123
- data/lib/exekutor/internal/configuration_builder.rb +49 -30
- data/lib/exekutor/internal/database_connection.rb +6 -0
- data/lib/exekutor/internal/executable.rb +12 -7
- data/lib/exekutor/internal/executor.rb +50 -21
- data/lib/exekutor/internal/hooks.rb +11 -8
- data/lib/exekutor/internal/listener.rb +85 -43
- data/lib/exekutor/internal/logger.rb +29 -10
- data/lib/exekutor/internal/provider.rb +96 -77
- data/lib/exekutor/internal/reserver.rb +66 -19
- data/lib/exekutor/internal/status_server.rb +87 -54
- data/lib/exekutor/job.rb +1 -1
- data/lib/exekutor/job_error.rb +1 -1
- data/lib/exekutor/job_options.rb +22 -13
- data/lib/exekutor/plugins/appsignal.rb +7 -5
- data/lib/exekutor/plugins.rb +8 -4
- data/lib/exekutor/queue.rb +69 -30
- data/lib/exekutor/version.rb +1 -1
- data/lib/exekutor/worker.rb +89 -48
- data/lib/exekutor.rb +2 -2
- data/lib/generators/exekutor/configuration_generator.rb +11 -6
- data/lib/generators/exekutor/install_generator.rb +24 -15
- data/lib/generators/exekutor/templates/install/functions/exekutor_broadcast_job_enqueued.sql +10 -0
- data/lib/generators/exekutor/templates/install/functions/exekutor_requeue_orphaned_jobs.sql +11 -0
- data/lib/generators/exekutor/templates/install/migrations/create_exekutor_schema.rb.erb +23 -22
- data/lib/generators/exekutor/templates/install/triggers/exekutor_broadcast_job_enqueued.sql +7 -0
- data/lib/generators/exekutor/templates/install/triggers/exekutor_requeue_orphaned_jobs.sql +5 -0
- data.tar.gz.sig +0 -0
- metadata +67 -23
- metadata.gz.sig +0 -0
- data/lib/generators/exekutor/templates/install/functions/job_notifier.sql +0 -7
- data/lib/generators/exekutor/templates/install/functions/requeue_orphaned_jobs.sql +0 -7
- data/lib/generators/exekutor/templates/install/triggers/notify_workers.sql +0 -6
- data/lib/generators/exekutor/templates/install/triggers/requeue_orphaned_jobs.sql +0 -5
data/lib/exekutor/worker.rb
CHANGED
@@ -23,64 +23,43 @@ module Exekutor
|
|
23
23
|
# @option config [Array<String>] :queues the queues to work on
|
24
24
|
# @option config [Integer] :min_threads the minimum number of execution threads that should be active
|
25
25
|
# @option config [Integer] :max_threads the maximum number of execution threads that may be active
|
26
|
-
# @option config [
|
27
|
-
#
|
26
|
+
# @option config [ActiveSupport::Duration] :max_thread_idletime the maximum duration a thread may be idle before
|
27
|
+
# being stopped
|
28
|
+
# @option config [ActiveSupport::Duration] :polling_interval the polling interval
|
28
29
|
# @option config [Float] :poling_jitter the polling jitter
|
29
30
|
# @option config [Boolean] :set_db_connection_name whether the DB connection name should be set
|
30
|
-
# @option config [Integer,Boolean] :wait_for_termination how long the worker should wait on jobs to be completed
|
31
|
+
# @option config [Integer,Boolean] :wait_for_termination how long the worker should wait on jobs to be completed
|
32
|
+
# before exiting
|
31
33
|
# @option config [Integer] :status_server_port the port to run the status server on
|
32
34
|
# @option config [String] :status_server_handler The name of the rack handler to use for the status server
|
33
|
-
# @option config [
|
35
|
+
# @option config [ActiveSupport::Duration] :healthcheck_timeout The timeout of a worker in minutes before the
|
36
|
+
# healthcheck server deems it as down
|
34
37
|
def initialize(config = {})
|
35
38
|
super()
|
36
39
|
@config = config
|
37
40
|
@record = create_record!
|
38
41
|
|
39
|
-
|
40
|
-
@executor = Internal::Executor.new(**config.slice(:min_threads, :max_threads, :max_thread_idletime,
|
41
|
-
:delete_completed_jobs, :delete_discarded_jobs,
|
42
|
-
:delete_failed_jobs))
|
42
|
+
provider_pool = create_provider_pool(config)
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
provider_threads += 1 if config[:status_server_port].to_i > 0
|
47
|
-
|
48
|
-
provider_pool = Concurrent::FixedThreadPool.new provider_threads, max_queue: provider_threads,
|
49
|
-
name: "exekutor-provider"
|
50
|
-
|
51
|
-
@provider = Internal::Provider.new reserver: @reserver, executor: @executor, pool: provider_pool,
|
52
|
-
**provider_options(config)
|
44
|
+
@executor = create_executor(config)
|
45
|
+
@provider = create_provider(config, @executor, provider_pool)
|
53
46
|
|
54
47
|
@executables = [@executor, @provider]
|
55
|
-
if config.fetch(:enable_listener, true)
|
56
|
-
|
57
|
-
**listener_options(config)
|
58
|
-
@executables << listener
|
59
|
-
end
|
60
|
-
if config[:status_server_port].to_i > 0
|
61
|
-
server = Internal::StatusServer.new worker: self, pool: provider_pool, **status_server_options(config)
|
62
|
-
@executables << server
|
63
|
-
end
|
48
|
+
create_listener(provider_pool, config) if config.fetch(:enable_listener, true)
|
49
|
+
create_status_server(provider_pool, config) if config[:status_server_port].to_i.positive?
|
64
50
|
@executables.freeze
|
65
|
-
|
66
|
-
@executor.after_execute(@record) do |_job, worker_info|
|
67
|
-
worker_info.heartbeat! rescue nil
|
68
|
-
@provider.poll if @provider.running?
|
69
|
-
end
|
70
|
-
@provider.on_queue_empty(@record) do |worker_info|
|
71
|
-
worker_info.heartbeat! rescue nil
|
72
|
-
@executor.prune_pool
|
73
|
-
end
|
74
51
|
end
|
75
52
|
|
76
53
|
# Starts the worker. Does nothing if the worker has already started.
|
77
54
|
# @return [Boolean] whether the worker was started
|
78
55
|
def start
|
79
56
|
return false unless compare_and_set_state(:pending, :started)
|
57
|
+
|
80
58
|
Internal::Hooks.run :startup, self do
|
81
59
|
@executables.each(&:start)
|
82
60
|
@record.update(status: "r")
|
83
61
|
end
|
62
|
+
|
84
63
|
true
|
85
64
|
end
|
86
65
|
|
@@ -89,22 +68,21 @@ module Exekutor
|
|
89
68
|
# @return true
|
90
69
|
def stop
|
91
70
|
Internal::Hooks.run :shutdown, self do
|
92
|
-
|
71
|
+
self.state = :stopped
|
93
72
|
unless @record.destroyed?
|
94
73
|
begin
|
95
74
|
@record.update(status: "s")
|
96
|
-
rescue
|
97
|
-
#ignored
|
75
|
+
rescue StandardError
|
76
|
+
# ignored
|
98
77
|
end
|
99
78
|
end
|
100
79
|
@executables.reverse_each(&:stop)
|
101
|
-
|
102
|
-
wait_for_termination @config[:wait_for_termination] if @config[:wait_for_termination]
|
80
|
+
wait_for_termination @config[:wait_for_termination]
|
103
81
|
|
104
82
|
begin
|
105
83
|
@record.destroy
|
106
|
-
rescue
|
107
|
-
#ignored
|
84
|
+
rescue StandardError
|
85
|
+
# ignored
|
108
86
|
end
|
109
87
|
@stop_event&.set if defined?(@stop_event)
|
110
88
|
end
|
@@ -121,8 +99,8 @@ module Exekutor
|
|
121
99
|
@executor.kill
|
122
100
|
begin
|
123
101
|
@record.destroy
|
124
|
-
rescue
|
125
|
-
#ignored
|
102
|
+
rescue StandardError
|
103
|
+
# ignored
|
126
104
|
end
|
127
105
|
true
|
128
106
|
end
|
@@ -138,7 +116,7 @@ module Exekutor
|
|
138
116
|
|
139
117
|
# Reserves and executes jobs.
|
140
118
|
def reserve_jobs
|
141
|
-
@provider.poll
|
119
|
+
@provider.poll if @provider&.running?
|
142
120
|
end
|
143
121
|
|
144
122
|
# The worker ID.
|
@@ -146,24 +124,76 @@ module Exekutor
|
|
146
124
|
@record.id
|
147
125
|
end
|
148
126
|
|
127
|
+
# @return [Time,nil] The timestamp of the last heartbeat. The timestamp is truncated to whole minutes.
|
149
128
|
def last_heartbeat
|
150
129
|
@record.last_heartbeat_at
|
151
130
|
end
|
152
131
|
|
132
|
+
# Returns the thread usage for this worker. The resulting hash will contain the following key-value pairs:
|
133
|
+
# - +:minimum+, (Integer) the minimum number of threads that should be active;
|
134
|
+
# - +:maximum+, (Integer) the maximum number of threads may should be active;
|
135
|
+
# - +:available+, (Integer) the number of threads that are available to execute new jobs;
|
136
|
+
# - +:usage_percent+, (Float, 0-100) the percentage of workers that are currently busy executing jobs.
|
137
|
+
# @return [Hash] the thread usage
|
153
138
|
def thread_stats
|
154
139
|
available = @executor.available_threads
|
140
|
+
usage_percent = (((100 - (available * 100.0 / @executor.maximum_threads))).round(2) if @executor.running?)
|
155
141
|
{
|
156
142
|
minimum: @executor.minimum_threads,
|
157
143
|
maximum: @executor.maximum_threads,
|
158
144
|
available: available,
|
159
|
-
usage_percent:
|
160
|
-
((1 - (available.to_f / @executor.maximum_threads)) * 100).round(2)
|
161
|
-
end
|
145
|
+
usage_percent: usage_percent
|
162
146
|
}
|
163
147
|
end
|
164
148
|
|
165
149
|
private
|
166
150
|
|
151
|
+
def create_provider_pool(config)
|
152
|
+
provider_threads = 1
|
153
|
+
provider_threads += 1 if config.fetch(:enable_listener, true)
|
154
|
+
provider_threads += 1 if config[:status_server_port].to_i.positive?
|
155
|
+
|
156
|
+
Concurrent::FixedThreadPool.new provider_threads, max_queue: provider_threads, name: "exekutor-provider"
|
157
|
+
end
|
158
|
+
|
159
|
+
def create_executor(worker_options)
|
160
|
+
executor = Internal::Executor.new(**executor_options(worker_options))
|
161
|
+
|
162
|
+
executor.after_execute(@record) do |_job, worker_info|
|
163
|
+
begin
|
164
|
+
worker_info.heartbeat!
|
165
|
+
rescue StandardError
|
166
|
+
# ignored
|
167
|
+
end
|
168
|
+
reserve_jobs
|
169
|
+
end
|
170
|
+
|
171
|
+
executor
|
172
|
+
end
|
173
|
+
|
174
|
+
def executor_options(worker_options)
|
175
|
+
worker_options.slice(:min_threads, :max_threads, :max_thread_idletime,
|
176
|
+
:delete_completed_jobs, :delete_discarded_jobs,
|
177
|
+
:delete_failed_jobs)
|
178
|
+
end
|
179
|
+
|
180
|
+
def create_provider(worker_options, executor, thread_pool)
|
181
|
+
@reserver = Internal::Reserver.new @record.id, **worker_options.slice(:queues, :min_priority, :max_priority)
|
182
|
+
provider = Internal::Provider.new reserver: @reserver, executor: executor, pool: thread_pool,
|
183
|
+
**provider_options(worker_options)
|
184
|
+
|
185
|
+
provider.on_queue_empty(@record, executor) do |worker_info, thr_executor|
|
186
|
+
begin
|
187
|
+
worker_info.heartbeat!
|
188
|
+
rescue StandardError
|
189
|
+
# ignored
|
190
|
+
end
|
191
|
+
thr_executor.prune_pool
|
192
|
+
end
|
193
|
+
|
194
|
+
provider
|
195
|
+
end
|
196
|
+
|
167
197
|
def provider_options(worker_options)
|
168
198
|
worker_options.slice(:polling_interval, :polling_jitter).transform_keys do |key|
|
169
199
|
case key
|
@@ -175,10 +205,21 @@ module Exekutor
|
|
175
205
|
end
|
176
206
|
end
|
177
207
|
|
208
|
+
def create_listener(provider_pool, config)
|
209
|
+
listener = Internal::Listener.new worker_id: @record.id, provider: @provider, pool: provider_pool,
|
210
|
+
**listener_options(config)
|
211
|
+
@executables << listener
|
212
|
+
end
|
213
|
+
|
178
214
|
def listener_options(worker_options)
|
179
215
|
worker_options.slice(:queues, :set_db_connection_name)
|
180
216
|
end
|
181
217
|
|
218
|
+
def create_status_server(provider_pool, config)
|
219
|
+
server = Internal::StatusServer.new worker: self, pool: provider_pool, **status_server_options(config)
|
220
|
+
@executables << server
|
221
|
+
end
|
222
|
+
|
182
223
|
def status_server_options(worker_options)
|
183
224
|
worker_options.slice(:status_server_port, :status_server_handler, :healthcheck_timeout).transform_keys do |key|
|
184
225
|
case key
|
data/lib/exekutor.rb
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
require_relative "exekutor/version"
|
4
4
|
|
5
|
+
# The Exekutor namespace
|
5
6
|
module Exekutor
|
6
|
-
|
7
7
|
# Base error class
|
8
8
|
class Error < StandardError; end
|
9
9
|
|
@@ -45,5 +45,5 @@ ActiveSupport.on_load(:active_record) do
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
Exekutor.private_constant
|
48
|
+
Exekutor.private_constant :Internal
|
49
49
|
ActiveSupport.run_load_hooks(:exekutor, Exekutor)
|
@@ -1,18 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require "rails/generators"
|
3
4
|
|
4
5
|
module Exekutor
|
6
|
+
# Generates a YAML configuration file
|
5
7
|
class ConfigurationGenerator < Rails::Generators::Base
|
6
|
-
desc
|
8
|
+
desc "Create YAML configuration for Exekutor"
|
7
9
|
|
8
|
-
class_option :identifier, type: :string, aliases: %i
|
10
|
+
class_option :identifier, type: :string, aliases: %i[--id], desc: "The worker identifier"
|
9
11
|
|
12
|
+
# Creates the configuration file at +config/exekutor.yml+. Uses the current worker configuration as the base.
|
10
13
|
def create_configuration_file
|
11
14
|
config = { queues: %w[queues to watch] }.merge(Exekutor.config.worker_options)
|
12
|
-
config[:status_port] =
|
15
|
+
config[:status_port] = 12_677
|
13
16
|
config[:set_db_connection_name] = true
|
14
17
|
config[:wait_for_termination] = 120
|
15
|
-
|
18
|
+
|
19
|
+
filename = "config/exekutor#{".#{options[:identifier]}" if options[:identifier]}.yml"
|
20
|
+
create_file filename, { "exekutor" => config.stringify_keys }.to_yaml
|
16
21
|
end
|
17
22
|
end
|
18
|
-
end
|
23
|
+
end
|
@@ -1,29 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require
|
2
|
+
|
3
|
+
require "rails/generators"
|
4
|
+
require "rails/generators/active_record"
|
4
5
|
|
5
6
|
module Exekutor
|
7
|
+
# Generates the initializer and migrations
|
6
8
|
class InstallGenerator < Rails::Generators::Base
|
7
9
|
include ActiveRecord::Generators::Migration
|
8
|
-
desc
|
10
|
+
desc "Create migrations for Exekutor"
|
9
11
|
|
10
|
-
TEMPLATE_DIR = File.join(__dir__,
|
12
|
+
TEMPLATE_DIR = File.join(__dir__, "templates/install")
|
11
13
|
source_paths << TEMPLATE_DIR
|
12
14
|
|
15
|
+
# Creates the initializer file at +config/initializers/exekutor.rb+
|
13
16
|
def create_initializer_file
|
14
|
-
template
|
17
|
+
template "initializers/exekutor.rb.erb", "config/initializers/exekutor.rb"
|
15
18
|
end
|
16
19
|
|
20
|
+
# Creates the migration file in the migrations folder
|
17
21
|
def create_migration_file
|
18
|
-
migration_template
|
19
|
-
|
20
|
-
|
21
|
-
copy_file "functions/#{function}.sql", Fx::Definition.new(name: function, version: 1).full_path
|
22
|
-
end
|
23
|
-
%w(notify_workers requeue_orphaned_jobs).each do |trigger|
|
24
|
-
copy_file "triggers/#{trigger}.sql", Fx::Definition.new(name: trigger, version: 1, type: "trigger").full_path
|
25
|
-
end
|
26
|
-
end
|
22
|
+
migration_template "migrations/create_exekutor_schema.rb.erb",
|
23
|
+
File.join(db_migrate_path, "create_exekutor_schema.rb")
|
24
|
+
create_fx_files
|
27
25
|
end
|
28
26
|
|
29
27
|
protected
|
@@ -39,5 +37,16 @@ module Exekutor
|
|
39
37
|
def trigger_sql(name)
|
40
38
|
File.read File.join(TEMPLATE_DIR, "triggers/#{name}.sql")
|
41
39
|
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def create_fx_files
|
44
|
+
return unless defined?(Fx)
|
45
|
+
|
46
|
+
%w[exekutor_broadcast_job_enqueued exekutor_requeue_orphaned_jobs].each do |name|
|
47
|
+
copy_file "functions/#{name}.sql", Fx::Definition.new(name: name, version: 1).full_path
|
48
|
+
copy_file "triggers/#{name}.sql", Fx::Definition.new(name: name, version: 1, type: "trigger").full_path
|
49
|
+
end
|
50
|
+
end
|
42
51
|
end
|
43
|
-
end
|
52
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
CREATE
|
2
|
+
OR REPLACE FUNCTION exekutor_broadcast_job_enqueued() RETURNS TRIGGER AS $$
|
3
|
+
BEGIN
|
4
|
+
PERFORM
|
5
|
+
pg_notify('exekutor::job_enqueued',
|
6
|
+
CONCAT('id:', NEW.id,';q:', NEW.queue,';p:', NEW.priority, ';t:', extract ('epoch' from NEW.scheduled_at)));
|
7
|
+
RETURN NULL;
|
8
|
+
END;
|
9
|
+
$$
|
10
|
+
LANGUAGE plpgsql
|
@@ -7,20 +7,20 @@ class CreateExekutorSchema < ActiveRecord::Migration[<%= migration_version %>]
|
|
7
7
|
|
8
8
|
t.jsonb :info, null: false
|
9
9
|
|
10
|
-
t.datetime :
|
11
|
-
t.datetime :last_heartbeat_at, null: false, default: -> {
|
10
|
+
t.datetime :started_at, null: false, default: -> { "now()" }
|
11
|
+
t.datetime :last_heartbeat_at, null: false, default: -> { "now()" }
|
12
12
|
|
13
|
-
t.column :status, :char, null: false, default:
|
13
|
+
t.column :status, :char, null: false, default: "i"
|
14
14
|
|
15
15
|
t.index [:hostname, :pid], unique: true
|
16
16
|
end
|
17
17
|
|
18
18
|
create_table :exekutor_jobs, id: :uuid do |t|
|
19
19
|
# Worker options
|
20
|
-
t.string :queue, null: false, default:
|
21
|
-
t.integer :priority, null: false, default:
|
22
|
-
t.datetime :enqueued_at, null: false, default: -> {
|
23
|
-
t.datetime :scheduled_at, null: false, default: -> {
|
20
|
+
t.string :queue, null: false, default: "default", limit: 200, index: true
|
21
|
+
t.integer :priority, null: false, default: 16_383, limit: 2
|
22
|
+
t.datetime :enqueued_at, null: false, default: -> { "now()" }
|
23
|
+
t.datetime :scheduled_at, null: false, default: -> { "now()" }
|
24
24
|
|
25
25
|
# Job options
|
26
26
|
t.uuid :active_job_id, null: false, index: true
|
@@ -28,53 +28,54 @@ class CreateExekutorSchema < ActiveRecord::Migration[<%= migration_version %>]
|
|
28
28
|
t.jsonb :options
|
29
29
|
|
30
30
|
# Execution options
|
31
|
-
t.column :status, :char, index: true, null: false, default:
|
31
|
+
t.column :status, :char, index: true, null: false, default: "p"
|
32
32
|
t.float :runtime
|
33
33
|
t.references :worker, type: :uuid, foreign_key: { to_table: :exekutor_workers, on_delete: :nullify }
|
34
34
|
|
35
|
-
t.index [:priority, :scheduled_at, :enqueued_at], where: %
|
35
|
+
t.index [:priority, :scheduled_at, :enqueued_at], where: %q("status"='p'),
|
36
|
+
name: :index_exekutor_jobs_on_dequeue_order
|
36
37
|
end
|
37
38
|
|
38
39
|
create_table :exekutor_job_errors, id: :uuid do |t|
|
39
40
|
t.references :job, type: :uuid, null: false, foreign_key: { to_table: :exekutor_jobs, on_delete: :cascade }
|
40
|
-
t.datetime :created_at, null: false, default: -> {
|
41
|
+
t.datetime :created_at, null: false, default: -> { "now()" }
|
41
42
|
t.jsonb :error, null: false
|
42
43
|
end
|
43
44
|
<% if defined? Fx %>
|
44
|
-
create_function :
|
45
|
-
create_trigger :
|
45
|
+
create_function :exekutor_broadcast_job_enqueued
|
46
|
+
create_trigger :exekutor_broadcast_job_enqueued, on: :exekutor_jobs
|
46
47
|
|
47
|
-
create_function :
|
48
|
-
create_trigger :
|
48
|
+
create_function :exekutor_requeue_orphaned_jobs
|
49
|
+
create_trigger :exekutor_requeue_orphaned_jobs, on: :exekutor_workers
|
49
50
|
<% else %>
|
50
51
|
reversible do |direction|
|
51
52
|
direction.up do
|
52
53
|
execute <<~SQL
|
53
|
-
<%= function_sql "
|
54
|
+
<%= function_sql "exekutor_broadcast_job_enqueued" %>
|
54
55
|
SQL
|
55
56
|
execute <<~SQL
|
56
|
-
<%= trigger_sql "
|
57
|
+
<%= trigger_sql "exekutor_broadcast_job_enqueued" %>
|
57
58
|
SQL
|
58
59
|
|
59
60
|
execute <<~SQL
|
60
|
-
<%= function_sql "
|
61
|
+
<%= function_sql "exekutor_requeue_orphaned_jobs" %>
|
61
62
|
SQL
|
62
63
|
execute <<~SQL
|
63
|
-
<%= trigger_sql "
|
64
|
+
<%= trigger_sql "exekutor_requeue_orphaned_jobs" %>
|
64
65
|
SQL
|
65
66
|
end
|
66
67
|
direction.down do
|
67
68
|
execute <<~SQL
|
68
|
-
DROP TRIGGER
|
69
|
+
DROP TRIGGER exekutor_requeue_orphaned_jobs ON exekutor_workers
|
69
70
|
SQL
|
70
71
|
execute <<~SQL
|
71
|
-
DROP FUNCTION
|
72
|
+
DROP FUNCTION exekutor_requeue_orphaned_jobs
|
72
73
|
SQL
|
73
74
|
execute <<~SQL
|
74
|
-
DROP TRIGGER
|
75
|
+
DROP TRIGGER exekutor_broadcast_job_enqueued ON exekutor_jobs
|
75
76
|
SQL
|
76
77
|
execute <<~SQL
|
77
|
-
DROP FUNCTION
|
78
|
+
DROP FUNCTION exekutor_broadcast_job_enqueued
|
78
79
|
SQL
|
79
80
|
end
|
80
81
|
end
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exekutor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roy
|
@@ -34,7 +34,7 @@ cert_chain:
|
|
34
34
|
LMMHpsz0vpxVqcs8USL9494hQUWRVlYd1F2PJeWtdKi0bU8dCduphJd8cTvCtS2l
|
35
35
|
CAY756btGBLeeWMBZ/DRMj1Cz3ifI9DV+KHqXg==
|
36
36
|
-----END CERTIFICATE-----
|
37
|
-
date: 2023-
|
37
|
+
date: 2023-12-19 00:00:00.000000000 Z
|
38
38
|
dependencies:
|
39
39
|
- !ruby/object:Gem::Dependency
|
40
40
|
name: activejob
|
@@ -152,20 +152,6 @@ dependencies:
|
|
152
152
|
- - "~>"
|
153
153
|
- !ruby/object:Gem::Version
|
154
154
|
version: '3.0'
|
155
|
-
- !ruby/object:Gem::Dependency
|
156
|
-
name: brakeman
|
157
|
-
requirement: !ruby/object:Gem::Requirement
|
158
|
-
requirements:
|
159
|
-
- - "~>"
|
160
|
-
- !ruby/object:Gem::Version
|
161
|
-
version: '5.4'
|
162
|
-
type: :development
|
163
|
-
prerelease: false
|
164
|
-
version_requirements: !ruby/object:Gem::Requirement
|
165
|
-
requirements:
|
166
|
-
- - "~>"
|
167
|
-
- !ruby/object:Gem::Version
|
168
|
-
version: '5.4'
|
169
155
|
- !ruby/object:Gem::Dependency
|
170
156
|
name: combustion
|
171
157
|
requirement: !ruby/object:Gem::Requirement
|
@@ -264,6 +250,48 @@ dependencies:
|
|
264
250
|
- - "~>"
|
265
251
|
- !ruby/object:Gem::Version
|
266
252
|
version: '1.21'
|
253
|
+
- !ruby/object:Gem::Dependency
|
254
|
+
name: rubocop-minitest
|
255
|
+
requirement: !ruby/object:Gem::Requirement
|
256
|
+
requirements:
|
257
|
+
- - "~>"
|
258
|
+
- !ruby/object:Gem::Version
|
259
|
+
version: '0.29'
|
260
|
+
type: :development
|
261
|
+
prerelease: false
|
262
|
+
version_requirements: !ruby/object:Gem::Requirement
|
263
|
+
requirements:
|
264
|
+
- - "~>"
|
265
|
+
- !ruby/object:Gem::Version
|
266
|
+
version: '0.29'
|
267
|
+
- !ruby/object:Gem::Dependency
|
268
|
+
name: rubocop-performance
|
269
|
+
requirement: !ruby/object:Gem::Requirement
|
270
|
+
requirements:
|
271
|
+
- - "~>"
|
272
|
+
- !ruby/object:Gem::Version
|
273
|
+
version: '1.16'
|
274
|
+
type: :development
|
275
|
+
prerelease: false
|
276
|
+
version_requirements: !ruby/object:Gem::Requirement
|
277
|
+
requirements:
|
278
|
+
- - "~>"
|
279
|
+
- !ruby/object:Gem::Version
|
280
|
+
version: '1.16'
|
281
|
+
- !ruby/object:Gem::Dependency
|
282
|
+
name: rubocop-rails
|
283
|
+
requirement: !ruby/object:Gem::Requirement
|
284
|
+
requirements:
|
285
|
+
- - "~>"
|
286
|
+
- !ruby/object:Gem::Version
|
287
|
+
version: '2.18'
|
288
|
+
type: :development
|
289
|
+
prerelease: false
|
290
|
+
version_requirements: !ruby/object:Gem::Requirement
|
291
|
+
requirements:
|
292
|
+
- - "~>"
|
293
|
+
- !ruby/object:Gem::Version
|
294
|
+
version: '2.18'
|
267
295
|
- !ruby/object:Gem::Dependency
|
268
296
|
name: simplecov
|
269
297
|
requirement: !ruby/object:Gem::Requirement
|
@@ -292,6 +320,20 @@ dependencies:
|
|
292
320
|
- - "~>"
|
293
321
|
- !ruby/object:Gem::Version
|
294
322
|
version: '0.9'
|
323
|
+
- !ruby/object:Gem::Dependency
|
324
|
+
name: webrick
|
325
|
+
requirement: !ruby/object:Gem::Requirement
|
326
|
+
requirements:
|
327
|
+
- - "~>"
|
328
|
+
- !ruby/object:Gem::Version
|
329
|
+
version: '1.6'
|
330
|
+
type: :development
|
331
|
+
prerelease: false
|
332
|
+
version_requirements: !ruby/object:Gem::Requirement
|
333
|
+
requirements:
|
334
|
+
- - "~>"
|
335
|
+
- !ruby/object:Gem::Version
|
336
|
+
version: '1.6'
|
295
337
|
- !ruby/object:Gem::Dependency
|
296
338
|
name: yard
|
297
339
|
requirement: !ruby/object:Gem::Requirement
|
@@ -320,8 +362,9 @@ dependencies:
|
|
320
362
|
- - "~>"
|
321
363
|
- !ruby/object:Gem::Version
|
322
364
|
version: '0.0'
|
323
|
-
description:
|
324
|
-
for jobs and `FOR UPDATE SKIP LOCKED` to
|
365
|
+
description: |
|
366
|
+
PostgreSQL backed active job adapter which uses `LISTEN/NOTIFY` to listen for jobs and `FOR UPDATE SKIP LOCKED` to
|
367
|
+
reserve jobs.
|
325
368
|
email:
|
326
369
|
- roy@devdicated.com
|
327
370
|
executables:
|
@@ -367,12 +410,12 @@ files:
|
|
367
410
|
- lib/exekutor/worker.rb
|
368
411
|
- lib/generators/exekutor/configuration_generator.rb
|
369
412
|
- lib/generators/exekutor/install_generator.rb
|
370
|
-
- lib/generators/exekutor/templates/install/functions/
|
371
|
-
- lib/generators/exekutor/templates/install/functions/
|
413
|
+
- lib/generators/exekutor/templates/install/functions/exekutor_broadcast_job_enqueued.sql
|
414
|
+
- lib/generators/exekutor/templates/install/functions/exekutor_requeue_orphaned_jobs.sql
|
372
415
|
- lib/generators/exekutor/templates/install/initializers/exekutor.rb.erb
|
373
416
|
- lib/generators/exekutor/templates/install/migrations/create_exekutor_schema.rb.erb
|
374
|
-
- lib/generators/exekutor/templates/install/triggers/
|
375
|
-
- lib/generators/exekutor/templates/install/triggers/
|
417
|
+
- lib/generators/exekutor/templates/install/triggers/exekutor_broadcast_job_enqueued.sql
|
418
|
+
- lib/generators/exekutor/templates/install/triggers/exekutor_requeue_orphaned_jobs.sql
|
376
419
|
homepage: https://github.com/devdicated/exekutor
|
377
420
|
licenses:
|
378
421
|
- MIT
|
@@ -381,6 +424,7 @@ metadata:
|
|
381
424
|
source_code_uri: https://github.com/devdicated/exekutor
|
382
425
|
changelog_uri: https://github.com/devdicated/exekutor/blob/master/CHANGELOG.md
|
383
426
|
allowed_push_host: https://rubygems.org
|
427
|
+
rubygems_mfa_required: 'true'
|
384
428
|
post_install_message:
|
385
429
|
rdoc_options: []
|
386
430
|
require_paths:
|
@@ -396,7 +440,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
396
440
|
- !ruby/object:Gem::Version
|
397
441
|
version: '0'
|
398
442
|
requirements: []
|
399
|
-
rubygems_version: 3.
|
443
|
+
rubygems_version: 3.4.13
|
400
444
|
signing_key:
|
401
445
|
specification_version: 4
|
402
446
|
summary: ActiveJob adapter with PostgreSQL backend.
|
metadata.gz.sig
CHANGED
Binary file
|