rails_async_migrations 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +138 -0
- data/.travis.yml +7 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +171 -0
- data/LICENSE.txt +21 -0
- data/README.md +162 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/generators/rails_async_migrations/install_generator.rb +22 -0
- data/lib/generators/rails_async_migrations/templates/create_async_schema_migrations.rb +11 -0
- data/lib/rails_async_migrations/config.rb +13 -0
- data/lib/rails_async_migrations/connection/active_record.rb +59 -0
- data/lib/rails_async_migrations/migration/check_queue.rb +72 -0
- data/lib/rails_async_migrations/migration/fire_migration.rb +56 -0
- data/lib/rails_async_migrations/migration/lock.rb +84 -0
- data/lib/rails_async_migrations/migration/method_added.rb +24 -0
- data/lib/rails_async_migrations/migration/overwrite.rb +28 -0
- data/lib/rails_async_migrations/migration/run.rb +73 -0
- data/lib/rails_async_migrations/migration/unlock.rb +42 -0
- data/lib/rails_async_migrations/migration.rb +23 -0
- data/lib/rails_async_migrations/models/async_schema_migration.rb +18 -0
- data/lib/rails_async_migrations/mutators/base.rb +9 -0
- data/lib/rails_async_migrations/mutators/trigger_callback.rb +57 -0
- data/lib/rails_async_migrations/mutators/turn_async.rb +22 -0
- data/lib/rails_async_migrations/mutators.rb +24 -0
- data/lib/rails_async_migrations/railtie.rb +7 -0
- data/lib/rails_async_migrations/tracer.rb +23 -0
- data/lib/rails_async_migrations/version.rb +3 -0
- data/lib/rails_async_migrations/workers/sidekiq/check_queue_worker.rb +16 -0
- data/lib/rails_async_migrations/workers/sidekiq/fire_migration_worker.rb +18 -0
- data/lib/rails_async_migrations/workers.rb +58 -0
- data/lib/rails_async_migrations.rb +35 -0
- data/lib/tasks/rails_async_migrations.rake +6 -0
- data/rails_async_migrations.gemspec +30 -0
- metadata +193 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
# we check the state of the queue and launch run worker if needed
|
2
|
+
module RailsAsyncMigrations
|
3
|
+
module Migration
|
4
|
+
class CheckQueue
|
5
|
+
def initialize
|
6
|
+
end
|
7
|
+
|
8
|
+
def perform
|
9
|
+
Tracer.new.verbose 'Check queue has been triggered'
|
10
|
+
|
11
|
+
return if has_failures?
|
12
|
+
return if has_on_going?
|
13
|
+
return if no_migration?
|
14
|
+
|
15
|
+
pending!
|
16
|
+
fire_migration
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def fire_migration
|
22
|
+
Tracer.new.verbose "Migration `#{current_migration.id}` will now be processed"
|
23
|
+
Workers.new(:fire_migration).perform(current_migration.id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def pending!
|
27
|
+
current_migration.update state: 'pending'
|
28
|
+
end
|
29
|
+
|
30
|
+
def current_migration
|
31
|
+
created_migration
|
32
|
+
end
|
33
|
+
|
34
|
+
def processing_migration
|
35
|
+
@processing_migration ||= AsyncSchemaMigration.processing.first
|
36
|
+
end
|
37
|
+
|
38
|
+
def pending_migration
|
39
|
+
@pending_migration ||= AsyncSchemaMigration.pending.first
|
40
|
+
end
|
41
|
+
|
42
|
+
def created_migration
|
43
|
+
@created_migration ||= AsyncSchemaMigration.created.first
|
44
|
+
end
|
45
|
+
|
46
|
+
def no_migration?
|
47
|
+
unless current_migration
|
48
|
+
Tracer.new.verbose 'No available migration in queue, cancelling check'
|
49
|
+
true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def has_on_going?
|
54
|
+
if pending_migration || processing_migration
|
55
|
+
Tracer.new.verbose 'Another migration under progress, cancelling check'
|
56
|
+
true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def has_failures?
|
61
|
+
if failed_migration
|
62
|
+
Tracer.new.verbose 'Failing migration blocking the queue, cancelling check'
|
63
|
+
true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def failed_migration
|
68
|
+
@failed_migration ||= AsyncSchemaMigration.failed.first
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# we check the state of the queue and launch run worker if needed
|
2
|
+
module RailsAsyncMigrations
|
3
|
+
module Migration
|
4
|
+
class FireMigration
|
5
|
+
attr_reader :migration
|
6
|
+
|
7
|
+
def initialize(migration_id)
|
8
|
+
@migration = AsyncSchemaMigration.find(migration_id)
|
9
|
+
end
|
10
|
+
|
11
|
+
def perform
|
12
|
+
return if done?
|
13
|
+
|
14
|
+
process!
|
15
|
+
run_migration
|
16
|
+
done!
|
17
|
+
|
18
|
+
check_queue
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def check_queue
|
24
|
+
Workers.new(:check_queue).perform
|
25
|
+
end
|
26
|
+
|
27
|
+
def run_migration
|
28
|
+
Migration::Run.new(migration.direction, migration.version).perform
|
29
|
+
rescue Exception => exception
|
30
|
+
failed_with! exception
|
31
|
+
raise
|
32
|
+
end
|
33
|
+
|
34
|
+
def done?
|
35
|
+
if migration.state == 'done'
|
36
|
+
Tracer.new.verbose "Migration #{migration.id} is already `done`, cancelling fire"
|
37
|
+
return
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def process!
|
42
|
+
migration.update! state: 'processing'
|
43
|
+
end
|
44
|
+
|
45
|
+
def done!
|
46
|
+
migration.update! state: 'done'
|
47
|
+
Tracer.new.verbose "Migration #{migration.id} was correctly processed"
|
48
|
+
end
|
49
|
+
|
50
|
+
def failed_with!(error)
|
51
|
+
migration.update! state: 'failed'
|
52
|
+
Tracer.new.verbose "Migration #{migration.id} failed with exception `#{error}`"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# locks any class methods depending on a configuration list
|
2
|
+
# this allow us to ignore migration without making
|
3
|
+
# a parallel pipeline system
|
4
|
+
module RailsAsyncMigrations
|
5
|
+
module Migration
|
6
|
+
class Lock
|
7
|
+
attr_reader :resource_class, :method_name
|
8
|
+
|
9
|
+
def initialize(resource_class, method_name)
|
10
|
+
@resource_class = resource_class
|
11
|
+
@method_name = method_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def perform
|
15
|
+
return false unless locked_method?
|
16
|
+
return false if unlocked?
|
17
|
+
|
18
|
+
preserve_method_logics
|
19
|
+
|
20
|
+
suspend_lock do
|
21
|
+
overwrite_method
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def suspend_lock(&block)
|
26
|
+
unlock
|
27
|
+
yield if block_given?
|
28
|
+
lock
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def unlocked?
|
34
|
+
locked == false
|
35
|
+
end
|
36
|
+
|
37
|
+
def clone_method_name
|
38
|
+
"async_#{method_name}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def preserve_method_logics
|
42
|
+
resource_class.define_method(clone_method_name, &captured_method)
|
43
|
+
end
|
44
|
+
|
45
|
+
def captured_method
|
46
|
+
resource_class.new.method(method_name).clone
|
47
|
+
end
|
48
|
+
|
49
|
+
def overwrite_method
|
50
|
+
resource_class.define_method(method_name, &overwrite_closure)
|
51
|
+
end
|
52
|
+
|
53
|
+
def overwrite_closure
|
54
|
+
proc do
|
55
|
+
Overwrite.new(self, __method__).perform
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def lockable?
|
60
|
+
unlocked? && locked_method?
|
61
|
+
end
|
62
|
+
|
63
|
+
def locked_method?
|
64
|
+
RailsAsyncMigrations.config.locked_methods.include? method_name
|
65
|
+
end
|
66
|
+
|
67
|
+
def lock
|
68
|
+
self.locked = true
|
69
|
+
end
|
70
|
+
|
71
|
+
def unlock
|
72
|
+
self.locked = false
|
73
|
+
end
|
74
|
+
|
75
|
+
def locked=(value)
|
76
|
+
resource_class.instance_variable_set(:@locked, value)
|
77
|
+
end
|
78
|
+
|
79
|
+
def locked
|
80
|
+
resource_class.instance_variable_get(:@locked)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# any method added within the synchronous migration
|
2
|
+
# with asynchronous directive will trigger this class
|
3
|
+
module RailsAsyncMigrations
|
4
|
+
module Migration
|
5
|
+
class MethodAdded
|
6
|
+
attr_reader :resource_class, :method_name
|
7
|
+
|
8
|
+
def initialize(resource_class, method_name)
|
9
|
+
@resource_class = resource_class
|
10
|
+
@method_name = method_name
|
11
|
+
end
|
12
|
+
|
13
|
+
def perform
|
14
|
+
lock_and_overwrite
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def lock_and_overwrite
|
20
|
+
Lock.new(resource_class, method_name).perform
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module RailsAsyncMigrations
|
2
|
+
module Migration
|
3
|
+
class Overwrite
|
4
|
+
attr_reader :instance, :method_name
|
5
|
+
|
6
|
+
def initialize(instance, method_name)
|
7
|
+
@instance = instance
|
8
|
+
@method_name = method_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def perform
|
12
|
+
dispatch_trace
|
13
|
+
trigger_callback
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def dispatch_trace
|
19
|
+
Tracer.new.verbose "#{instance.class}\##{method_name} was called in a locked state"
|
20
|
+
end
|
21
|
+
|
22
|
+
def trigger_callback
|
23
|
+
instance.send(:trigger_callback, method_name)
|
24
|
+
rescue NoMethodError
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# to run actual migration we need to require the migration files
|
2
|
+
module RailsAsyncMigrations
|
3
|
+
module Migration
|
4
|
+
class Run
|
5
|
+
attr_reader :direction, :version, :migration
|
6
|
+
|
7
|
+
def initialize(direction, version)
|
8
|
+
@direction = direction
|
9
|
+
@version = version
|
10
|
+
@migration = migration_from version
|
11
|
+
|
12
|
+
ensure_data_consistency
|
13
|
+
require "#{Rails.root}/#{migration.filename}" if defined? Rails
|
14
|
+
end
|
15
|
+
|
16
|
+
def perform
|
17
|
+
unlock_migration_methods
|
18
|
+
delete_migration_state
|
19
|
+
run_migration
|
20
|
+
delete_migration_state
|
21
|
+
lock_migration_methods
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def migration_from(version)
|
27
|
+
Connection::ActiveRecord.new(direction).migration_from version
|
28
|
+
end
|
29
|
+
|
30
|
+
def run_migration
|
31
|
+
migrator_instance.migrate
|
32
|
+
end
|
33
|
+
|
34
|
+
def migrator_instance
|
35
|
+
@migrator_instance ||= ::ActiveRecord::Migrator.new(direction.to_sym, [migration])
|
36
|
+
end
|
37
|
+
|
38
|
+
def schema_migration
|
39
|
+
@schema_migration ||= ActiveRecord::SchemaMigration.find_by(version: version)
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete_migration_state
|
43
|
+
schema_migration&.delete
|
44
|
+
end
|
45
|
+
|
46
|
+
def class_name
|
47
|
+
migration.name.constantize
|
48
|
+
end
|
49
|
+
|
50
|
+
def locked_methods
|
51
|
+
RailsAsyncMigrations.config.locked_methods
|
52
|
+
end
|
53
|
+
|
54
|
+
def unlock_migration_methods
|
55
|
+
locked_methods.each do |method_name|
|
56
|
+
Migration::Unlock.new(class_name, method_name).perform
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def lock_migration_methods
|
61
|
+
locked_methods.each do |method_name|
|
62
|
+
Migration::Lock.new(class_name, method_name).perform
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def ensure_data_consistency
|
67
|
+
unless migration
|
68
|
+
raise RailsAsyncMigrations::Error, "No migration from version `#{version}`"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module RailsAsyncMigrations
|
2
|
+
module Migration
|
3
|
+
class Unlock
|
4
|
+
attr_reader :resource_class, :method_name
|
5
|
+
|
6
|
+
def initialize(resource_class, method_name)
|
7
|
+
@resource_class = resource_class
|
8
|
+
@method_name = method_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def perform
|
12
|
+
restore_original_method
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def restore_original_method
|
18
|
+
if valid?
|
19
|
+
Lock.new(resource_class, method_name).suspend_lock do
|
20
|
+
resource_class.define_method(method_name, &method_clone)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def valid?
|
26
|
+
temporary_instance.respond_to? clone_method_name
|
27
|
+
end
|
28
|
+
|
29
|
+
def clone_method_name
|
30
|
+
"async_#{method_name}"
|
31
|
+
end
|
32
|
+
|
33
|
+
def method_clone
|
34
|
+
temporary_instance.method(clone_method_name).clone
|
35
|
+
end
|
36
|
+
|
37
|
+
def temporary_instance
|
38
|
+
@temporary_instance ||= resource_class.new
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rails_async_migrations/migration/check_queue'
|
2
|
+
require 'rails_async_migrations/migration/fire_migration'
|
3
|
+
require 'rails_async_migrations/migration/lock'
|
4
|
+
require 'rails_async_migrations/migration/method_added'
|
5
|
+
require 'rails_async_migrations/migration/overwrite'
|
6
|
+
require 'rails_async_migrations/migration/run'
|
7
|
+
require 'rails_async_migrations/migration/unlock'
|
8
|
+
|
9
|
+
# when included this class is the gateway
|
10
|
+
# to the method locking system
|
11
|
+
module RailsAsyncMigrations
|
12
|
+
module Migration
|
13
|
+
def self.included(base)
|
14
|
+
base.extend ClassMethods
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
def method_added(name)
|
19
|
+
MethodAdded.new(self, name).perform
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class AsyncSchemaMigration < ActiveRecord::Base
|
2
|
+
validates :version, presence: true
|
3
|
+
validates :state, inclusion: { in: %w[created pending processing done failed] }
|
4
|
+
validates :direction, inclusion: { in: %w[up down] }
|
5
|
+
|
6
|
+
after_save :trace
|
7
|
+
|
8
|
+
scope :created, -> { where(state: 'created').by_version }
|
9
|
+
scope :pending, -> { where(state: 'pending').by_version }
|
10
|
+
scope :processing, -> { where(state: 'processing').by_version }
|
11
|
+
scope :done, -> { where(state: 'done').by_version }
|
12
|
+
scope :failed, -> { where(state: 'failed').by_version }
|
13
|
+
scope :by_version, -> { order(version: :asc) }
|
14
|
+
|
15
|
+
def trace
|
16
|
+
RailsAsyncMigrations::Tracer.new.verbose "Asynchronous migration `#{id}` is now `#{state}`"
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module RailsAsyncMigrations
|
2
|
+
module Mutators
|
3
|
+
class TriggerCallback < Base
|
4
|
+
attr_reader :instance, :method_name
|
5
|
+
|
6
|
+
def initialize(instance, method_name)
|
7
|
+
@instance = instance
|
8
|
+
@method_name = method_name
|
9
|
+
end
|
10
|
+
|
11
|
+
# this method can be called multiple times (we should see what manages this actually)
|
12
|
+
# if you use up down and change it'll be called 3 times for example
|
13
|
+
def perform
|
14
|
+
unless active_record.allowed_direction?
|
15
|
+
Tracer.new.verbose "Direction `#{direction}` not allowed."
|
16
|
+
return
|
17
|
+
end
|
18
|
+
|
19
|
+
enqueue_asynchronous unless already_enqueued?
|
20
|
+
check_queue
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def enqueue_asynchronous
|
26
|
+
AsyncSchemaMigration.create!(
|
27
|
+
version: active_record.current_version,
|
28
|
+
direction: active_record.current_direction,
|
29
|
+
state: 'created'
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def already_enqueued?
|
34
|
+
AsyncSchemaMigration.find_by(
|
35
|
+
version: active_record.current_version,
|
36
|
+
direction: active_record.current_direction
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
def check_queue
|
41
|
+
Workers.new(:check_queue).perform
|
42
|
+
end
|
43
|
+
|
44
|
+
def active_record
|
45
|
+
@active_record ||= Connection::ActiveRecord.new(direction)
|
46
|
+
end
|
47
|
+
|
48
|
+
def direction
|
49
|
+
if instance.reverting?
|
50
|
+
:down
|
51
|
+
else
|
52
|
+
:up
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RailsAsyncMigrations
|
2
|
+
module Mutators
|
3
|
+
class TurnAsync < Base
|
4
|
+
attr_reader :instance
|
5
|
+
|
6
|
+
def initialize(instance)
|
7
|
+
@instance = instance
|
8
|
+
end
|
9
|
+
|
10
|
+
def perform
|
11
|
+
Tracer.new.verbose '`turn_async` has been triggered'
|
12
|
+
alter_migration
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def alter_migration
|
18
|
+
migration_class.include RailsAsyncMigrations::Migration
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rails_async_migrations/mutators/base'
|
2
|
+
require 'rails_async_migrations/mutators/turn_async'
|
3
|
+
require 'rails_async_migrations/mutators/trigger_callback'
|
4
|
+
|
5
|
+
# this is the entry point of the gem as it adds methods to the current migration class
|
6
|
+
# the `self` represents the class being ran so we have to be careful as not to conflict
|
7
|
+
# with the original ActiveRecord names
|
8
|
+
module RailsAsyncMigrations
|
9
|
+
module Mutators
|
10
|
+
private
|
11
|
+
|
12
|
+
def turn_async
|
13
|
+
TurnAsync.new(self).perform
|
14
|
+
end
|
15
|
+
|
16
|
+
# # the following methods are internal mechanics
|
17
|
+
# # do not overwrite those methods if you don't know
|
18
|
+
# # exactly what you're doing
|
19
|
+
|
20
|
+
def trigger_callback(method)
|
21
|
+
TriggerCallback.new(self, method).perform
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# log things and dispatch them wherever
|
2
|
+
# depending on the context mode
|
3
|
+
module RailsAsyncMigrations
|
4
|
+
class Tracer
|
5
|
+
def initialize
|
6
|
+
end
|
7
|
+
|
8
|
+
def verbose(text)
|
9
|
+
return unless verbose?
|
10
|
+
puts text
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def verbose?
|
16
|
+
mode == :verbose
|
17
|
+
end
|
18
|
+
|
19
|
+
def mode
|
20
|
+
RailsAsyncMigrations.config.mode
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# we check the state of the queue and launch run worker if needed
|
2
|
+
module RailsAsyncMigrations
|
3
|
+
class Workers
|
4
|
+
module Sidekiq
|
5
|
+
class CheckQueueWorker
|
6
|
+
include ::Sidekiq::Worker
|
7
|
+
|
8
|
+
sidekiq_options queue: :default
|
9
|
+
|
10
|
+
def perform
|
11
|
+
Migration::CheckQueue.new.perform
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# we check the state of the queue and launch run worker if needed
|
2
|
+
module RailsAsyncMigrations
|
3
|
+
class Workers
|
4
|
+
module Sidekiq
|
5
|
+
class FireMigrationWorker
|
6
|
+
include ::Sidekiq::Worker
|
7
|
+
|
8
|
+
sidekiq_options queue: :default
|
9
|
+
|
10
|
+
def perform(migration_id)
|
11
|
+
Migration::FireMigration.new(
|
12
|
+
migration_id
|
13
|
+
).perform
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# we check the state of the queue and launch run worker if needed
|
2
|
+
module RailsAsyncMigrations
|
3
|
+
class Workers
|
4
|
+
ALLOWED = [:check_queue, :fire_migration].freeze
|
5
|
+
attr_reader :called_worker
|
6
|
+
|
7
|
+
def initialize(called_worker)
|
8
|
+
@called_worker = called_worker # :check_queue, :fire_migration
|
9
|
+
ensure_worker_presence
|
10
|
+
end
|
11
|
+
|
12
|
+
def perform(args = nil)
|
13
|
+
return unless ALLOWED.include? called_worker
|
14
|
+
self.send called_worker, *args
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def check_queue(*args)
|
20
|
+
case workers_type
|
21
|
+
when :sidekiq
|
22
|
+
Workers::Sidekiq::CheckQueueWorker.perform_async(*args)
|
23
|
+
when :delayed_job
|
24
|
+
::Delayed::Job.enqueue Migration::CheckQueue.new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def fire_migration(*args)
|
29
|
+
case workers_type
|
30
|
+
when :sidekiq
|
31
|
+
Workers::Sidekiq::FireMigrationWorker.perform_async(*args)
|
32
|
+
when :delayed_job
|
33
|
+
::Delayed::Job.enqueue Migration::FireMigration.new(*args)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def workers_type
|
38
|
+
RailsAsyncMigrations.config.workers
|
39
|
+
end
|
40
|
+
|
41
|
+
def ensure_worker_presence
|
42
|
+
case workers_type
|
43
|
+
when :sidekiq
|
44
|
+
require 'sidekiq'
|
45
|
+
require 'rails_async_migrations/workers/sidekiq/check_queue_worker'
|
46
|
+
require 'rails_async_migrations/workers/sidekiq/fire_migration_worker'
|
47
|
+
|
48
|
+
unless defined? ::Sidekiq::Worker
|
49
|
+
raise Error, 'Please install Sidekiq before to set it as worker adapter'
|
50
|
+
end
|
51
|
+
when :delayed_job
|
52
|
+
unless defined? ::Delayed::Job
|
53
|
+
raise Error, 'Please install Delayed::Job before to set it as worker adapter'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|