chained_job 0.1.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/bin/console +10 -0
- data/bin/setup +8 -0
- data/lib/chained_job.rb +28 -0
- data/lib/chained_job/config.rb +32 -0
- data/lib/chained_job/helpers.rb +11 -0
- data/lib/chained_job/middleware.rb +24 -0
- data/lib/chained_job/process.rb +51 -0
- data/lib/chained_job/start_chains.rb +74 -0
- data/lib/chained_job/version.rb +5 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7a8aa04f7ae42cb12af32784e969ce63952884ff5db3e6e435943bcf1112f50b
|
4
|
+
data.tar.gz: db0cc9308feec6d98a8d8444f7c96da901b204f14d265cc1f6b20df9eab6a72a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b865a3f752707bea1255f0bbc76bbb29ed901ab83b05092ef4c03274651d7b0eadee5307f6f28610a0cbfe374ede0e141a482c837b9677ed2defb52923b03190
|
7
|
+
data.tar.gz: 6b3b01a064ed9a76948196c16715c24226382c6fed5925a5fa3f53455a0b6b7d7976a066721de58746b0cb1bf6d3ed28899dd97901bfbf510f28b38f40a033dd
|
data/bin/console
ADDED
data/bin/setup
ADDED
data/lib/chained_job.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'chained_job/config'
|
4
|
+
require 'chained_job/middleware'
|
5
|
+
require 'chained_job/version'
|
6
|
+
|
7
|
+
module ChainedJob
|
8
|
+
class Error < StandardError; end
|
9
|
+
class ConfigurationError < Error; end
|
10
|
+
|
11
|
+
module_function
|
12
|
+
|
13
|
+
def redis
|
14
|
+
config.redis || raise(ConfigurationError, 'Redis is not configured')
|
15
|
+
end
|
16
|
+
|
17
|
+
def logger
|
18
|
+
config.logger
|
19
|
+
end
|
20
|
+
|
21
|
+
def config
|
22
|
+
@config ||= ChainedJob::Config.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def configure
|
26
|
+
yield(config)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module ChainedJob
|
6
|
+
class Config
|
7
|
+
DEFAULT_ARGUMENTS_BATCH_SIZE = 1_000
|
8
|
+
DEFAULT_ARGUMENTS_QUEUE_EXPIRATION = 7 * 24 * 60 * 60 # 7 days
|
9
|
+
|
10
|
+
attr_accessor(
|
11
|
+
:arguments_batch_size,
|
12
|
+
:arguments_queue_expiration,
|
13
|
+
:around_start_chains,
|
14
|
+
:around_chain_process,
|
15
|
+
:debug,
|
16
|
+
:logger,
|
17
|
+
:redis,
|
18
|
+
)
|
19
|
+
|
20
|
+
def initialize
|
21
|
+
self.arguments_batch_size = DEFAULT_ARGUMENTS_BATCH_SIZE
|
22
|
+
self.arguments_queue_expiration = DEFAULT_ARGUMENTS_QUEUE_EXPIRATION
|
23
|
+
|
24
|
+
self.logger = ::Logger.new(STDOUT)
|
25
|
+
|
26
|
+
self.around_start_chains = ->(_options, &block) { block.call }
|
27
|
+
self.around_chain_process = ->(_options, &block) { block.call }
|
28
|
+
|
29
|
+
self.debug = true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'chained_job/start_chains'
|
4
|
+
require 'chained_job/process'
|
5
|
+
|
6
|
+
module ChainedJob
|
7
|
+
module Middleware
|
8
|
+
def perform(worker_id = nil)
|
9
|
+
if worker_id
|
10
|
+
ChainedJob::Process.run(self, worker_id)
|
11
|
+
else
|
12
|
+
ChainedJob::StartChains.run(self.class, array_of_job_arguments, parallelism)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def array_of_job_arguments
|
17
|
+
raise NoMethodError, 'undefined method array_of_job_arguments'
|
18
|
+
end
|
19
|
+
|
20
|
+
def parallelism
|
21
|
+
raise NoMethodError, 'undefined method parallelism'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'chained_job/helpers'
|
4
|
+
|
5
|
+
module ChainedJob
|
6
|
+
class Process
|
7
|
+
def self.run(job_instance, worker_id)
|
8
|
+
new(job_instance, worker_id).run
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :job_instance, :worker_id
|
12
|
+
|
13
|
+
def initialize(job_instance, worker_id)
|
14
|
+
@job_instance = job_instance
|
15
|
+
@worker_id = worker_id
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
with_hooks do
|
20
|
+
return log_finished_worker unless argument
|
21
|
+
|
22
|
+
job_instance.process(argument)
|
23
|
+
job_instance.class.perform_later(worker_id)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def with_hooks
|
30
|
+
ChainedJob.config.around_chain_process.call(options) { yield }
|
31
|
+
end
|
32
|
+
|
33
|
+
def options
|
34
|
+
{ job_class: job_instance.class, worker_id: worker_id }
|
35
|
+
end
|
36
|
+
|
37
|
+
def log_finished_worker
|
38
|
+
ChainedJob.logger.info(
|
39
|
+
"#{job_instance.class} worker #{worker_id} finished"
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def argument
|
44
|
+
@argument ||= ChainedJob.redis.lpop(redis_key)
|
45
|
+
end
|
46
|
+
|
47
|
+
def redis_key
|
48
|
+
Helpers.redis_key(job_instance.class)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'chained_job/helpers'
|
4
|
+
|
5
|
+
module ChainedJob
|
6
|
+
class StartChains
|
7
|
+
def self.run(job_class, array_of_job_arguments, parallelism)
|
8
|
+
new(job_class, array_of_job_arguments, parallelism).run
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :job_class, :array_of_job_arguments, :parallelism
|
12
|
+
|
13
|
+
def initialize(job_class, array_of_job_arguments, parallelism)
|
14
|
+
@job_class = job_class
|
15
|
+
@array_of_job_arguments = array_of_job_arguments
|
16
|
+
@parallelism = parallelism
|
17
|
+
end
|
18
|
+
|
19
|
+
def run
|
20
|
+
with_hooks do
|
21
|
+
redis.del(redis_key)
|
22
|
+
|
23
|
+
return unless array_of_job_arguments.count.positive?
|
24
|
+
|
25
|
+
store_job_arguments
|
26
|
+
|
27
|
+
log_chained_job_start
|
28
|
+
|
29
|
+
parallelism.times { |worked_id| job_class.perform_later(worked_id) }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def with_hooks
|
36
|
+
ChainedJob.config.around_start_chains.call(options) { yield }
|
37
|
+
end
|
38
|
+
|
39
|
+
def options
|
40
|
+
{
|
41
|
+
job_class: job_class,
|
42
|
+
array_of_job_arguments: array_of_job_arguments,
|
43
|
+
parallelism: parallelism,
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def store_job_arguments
|
48
|
+
array_of_job_arguments.each_slice(config.arguments_batch_size) do |sublist|
|
49
|
+
redis.rpush(redis_key, sublist)
|
50
|
+
end
|
51
|
+
|
52
|
+
redis.expire(redis_key, config.arguments_queue_expiration)
|
53
|
+
end
|
54
|
+
|
55
|
+
def log_chained_job_start
|
56
|
+
ChainedJob.logger.info(
|
57
|
+
"#{job_class} starting #{parallelism} workers "\
|
58
|
+
"processing #{array_of_job_arguments.count} items"
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
def redis
|
63
|
+
ChainedJob.redis
|
64
|
+
end
|
65
|
+
|
66
|
+
def redis_key
|
67
|
+
Helpers.redis_key(job_class)
|
68
|
+
end
|
69
|
+
|
70
|
+
def config
|
71
|
+
ChainedJob.config
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: chained_job
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mantas Kūjalis
|
8
|
+
- Titas Norkūnas
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2020-04-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.17'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.17'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: minitest
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '5.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '5.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rake
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '12.0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '12.0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rubocop-vinted
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0.3'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.3'
|
70
|
+
description: Chained job allows you to define an array of queued jobs that should
|
71
|
+
be run in sequence after the main job has been executed successfully.
|
72
|
+
email:
|
73
|
+
- mantas.kujalis@vinted.com
|
74
|
+
- titas@vinted.com
|
75
|
+
executables:
|
76
|
+
- setup
|
77
|
+
- console
|
78
|
+
extensions: []
|
79
|
+
extra_rdoc_files: []
|
80
|
+
files:
|
81
|
+
- bin/console
|
82
|
+
- bin/setup
|
83
|
+
- lib/chained_job.rb
|
84
|
+
- lib/chained_job/config.rb
|
85
|
+
- lib/chained_job/helpers.rb
|
86
|
+
- lib/chained_job/middleware.rb
|
87
|
+
- lib/chained_job/process.rb
|
88
|
+
- lib/chained_job/start_chains.rb
|
89
|
+
- lib/chained_job/version.rb
|
90
|
+
homepage: https://github.com/vinted/chained_job
|
91
|
+
licenses:
|
92
|
+
- MIT
|
93
|
+
metadata: {}
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
requirements: []
|
109
|
+
rubygems_version: 3.0.3
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: Chained job helper
|
113
|
+
test_files: []
|