chained_job 0.1.2 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0cf0d92c19a3955df5206dc54e7ca3883120a73fdcc1fd8743495f9c37690308
4
- data.tar.gz: '09617e3e0873985b586da6903f604e89f1d429bab84bf99e88d652d807408d08'
3
+ metadata.gz: 84c8c12fdb15c63dfa9fe2cb031382284e0eedcb2fdfad5f5af4d5dc8f01370a
4
+ data.tar.gz: 467051fa730945c836e93222c8057b9c8e2a9d635a46e550db299cc99b36f380
5
5
  SHA512:
6
- metadata.gz: 37ca1b1aa5dc58b495a0dac015b024919713ecf4a6ccfc63b252f81f1adfb9090b702e6175f3f9aaa5da85a0293e043e398226a67c684138bffceb28c819db63
7
- data.tar.gz: dbe7e4ce4dd1c92f955e62f0e0cf806df9a580fa54658960ee9889c92adb02eb30f8de3b61c57b9e652a1fff1167f86cb8c0caf613e43ca2ac07fc7b77bf2dfb
6
+ metadata.gz: b590497db0ae0fdb36f2e928da3bcb72c5c4ae7eabe5225a863d301ec27f462dda2f13c0a57f941eec07cf96b347935eed995835c67a89d3617d184516709f7a
7
+ data.tar.gz: 98146d3133f14943b3a262014e6dba6e729cc019e945af887de311e416995b5dc52f4ba8f236c0d8df941cfec208de72712b19f1ad5ff8aeb89ceba2e4dd0d6b
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'chained_job/helpers'
4
+
5
+ module ChainedJob
6
+ class CleanUpQueue
7
+ def self.run(job_class)
8
+ new(job_class).run
9
+ end
10
+
11
+ TRIM_STEP_SIZE = 1_000
12
+
13
+ attr_reader :job_class
14
+
15
+ def initialize(job_class)
16
+ @job_class = job_class
17
+ end
18
+
19
+ # rubocop:disable Metrics/AbcSize
20
+ def run
21
+ loop do
22
+ tag = ChainedJob.redis.spop(tag_list)
23
+
24
+ break unless tag
25
+
26
+ redis_key = Helpers.redis_key(job_key, tag)
27
+ size = ChainedJob.redis.llen(redis_key)
28
+ (size / TRIM_STEP_SIZE).times { ChainedJob.redis.ltrim(redis_key, 0, -TRIM_STEP_SIZE) }
29
+
30
+ ChainedJob.redis.del(redis_key)
31
+ end
32
+ end
33
+ # rubocop:enable Metrics/AbcSize
34
+
35
+ private
36
+
37
+ def tag_list
38
+ @tag_list ||= Helpers.tag_list(job_key)
39
+ end
40
+
41
+ def job_key
42
+ @job_key ||= Helpers.job_key(job_class)
43
+ end
44
+ end
45
+ end
@@ -12,9 +12,12 @@ module ChainedJob
12
12
  :arguments_queue_expiration,
13
13
  :around_start_chains,
14
14
  :around_chain_process,
15
+ :around_array_of_job_arguments,
16
+ :after_worker_finished,
15
17
  :debug,
16
18
  :logger,
17
19
  :redis,
20
+ :queue,
18
21
  )
19
22
 
20
23
  def initialize
@@ -25,6 +28,8 @@ module ChainedJob
25
28
 
26
29
  self.around_start_chains = ->(_options, &block) { block.call }
27
30
  self.around_chain_process = ->(_options, &block) { block.call }
31
+ self.around_array_of_job_arguments = ->(_options, &block) { block.call }
32
+ self.after_worker_finished = ->(_options) {}
28
33
 
29
34
  self.debug = true
30
35
  end
@@ -4,8 +4,16 @@ module ChainedJob
4
4
  module Helpers
5
5
  module_function
6
6
 
7
- def redis_key(job_class)
7
+ def job_key(job_class)
8
8
  "chained_job:#{job_class}"
9
9
  end
10
+
11
+ def redis_key(job_key, tag)
12
+ "#{job_key}:#{tag}"
13
+ end
14
+
15
+ def tag_list(prefix)
16
+ "#{prefix}:tags"
17
+ end
10
18
  end
11
19
  end
@@ -5,14 +5,23 @@ require 'chained_job/process'
5
5
 
6
6
  module ChainedJob
7
7
  module Middleware
8
- def perform(worker_id = nil)
8
+ def self.included(base)
9
+ base.queue_as ChainedJob.config.queue if ChainedJob.config.queue
10
+ end
11
+
12
+ def perform(worker_id = nil, tag = nil)
9
13
  if worker_id
10
- ChainedJob::Process.run(self, worker_id)
14
+ ChainedJob::Process.run(self, worker_id, tag)
11
15
  else
12
- ChainedJob::StartChains.run(self.class, array_of_job_arguments, parallelism)
16
+ ChainedJob::StartChains.run(self.class, arguments_array, parallelism)
13
17
  end
14
18
  end
15
19
 
20
+ def arguments_array
21
+ options = { job_class: self.class }
22
+ ChainedJob.config.around_array_of_job_arguments.call(options) { array_of_job_arguments }
23
+ end
24
+
16
25
  def array_of_job_arguments
17
26
  raise NoMethodError, 'undefined method array_of_job_arguments'
18
27
  end
@@ -4,23 +4,24 @@ require 'chained_job/helpers'
4
4
 
5
5
  module ChainedJob
6
6
  class Process
7
- def self.run(job_instance, worker_id)
8
- new(job_instance, worker_id).run
7
+ def self.run(job_instance, worker_id, job_tag)
8
+ new(job_instance, worker_id, job_tag).run
9
9
  end
10
10
 
11
- attr_reader :job_instance, :worker_id
11
+ attr_reader :job_instance, :worker_id, :job_tag
12
12
 
13
- def initialize(job_instance, worker_id)
13
+ def initialize(job_instance, worker_id, job_tag)
14
14
  @job_instance = job_instance
15
15
  @worker_id = worker_id
16
+ @job_tag = job_tag
16
17
  end
17
18
 
18
19
  def run
19
20
  with_hooks do
20
- return log_finished_worker unless argument
21
+ return finished_worker unless argument
21
22
 
22
23
  job_instance.process(argument)
23
- job_instance.class.perform_later(worker_id)
24
+ job_instance.class.perform_later(worker_id, job_tag)
24
25
  end
25
26
  end
26
27
 
@@ -31,12 +32,18 @@ module ChainedJob
31
32
  end
32
33
 
33
34
  def options
34
- { job_class: job_instance.class, worker_id: worker_id }
35
+ @options ||= { job_class: job_instance.class, worker_id: worker_id }
36
+ end
37
+
38
+ def finished_worker
39
+ log_finished_worker
40
+
41
+ ChainedJob.config.after_worker_finished&.call(options)
35
42
  end
36
43
 
37
44
  def log_finished_worker
38
45
  ChainedJob.logger.info(
39
- "#{job_instance.class} worker #{worker_id} finished"
46
+ "#{job_instance.class}:#{job_tag} worker #{worker_id} finished"
40
47
  )
41
48
  end
42
49
 
@@ -45,7 +52,11 @@ module ChainedJob
45
52
  end
46
53
 
47
54
  def redis_key
48
- Helpers.redis_key(job_instance.class)
55
+ Helpers.redis_key(job_key, job_tag)
56
+ end
57
+
58
+ def job_key
59
+ Helpers.job_key(job_instance.class)
49
60
  end
50
61
  end
51
62
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'chained_job/helpers'
4
+ require 'chained_job/clean_up_queue'
5
+ require 'chained_job/store_job_arguments'
4
6
 
5
7
  module ChainedJob
6
8
  class StartChains
@@ -16,19 +18,23 @@ module ChainedJob
16
18
  @parallelism = parallelism
17
19
  end
18
20
 
21
+ # rubocop:disable Metrics/AbcSize
19
22
  def run
20
23
  with_hooks do
21
- redis.del(redis_key)
24
+ log_chained_job_cleanup
25
+
26
+ ChainedJob::CleanUpQueue.run(job_class)
22
27
 
23
28
  next unless array_of_job_arguments.count.positive?
24
29
 
25
- store_job_arguments
30
+ ChainedJob::StoreJobArguments.run(job_class, job_tag, array_of_job_arguments)
26
31
 
27
32
  log_chained_job_start
28
33
 
29
- parallelism.times { |worked_id| job_class.perform_later(worked_id) }
34
+ parallelism.times { |worked_id| job_class.perform_later(worked_id, job_tag) }
30
35
  end
31
36
  end
37
+ # rubocop:enable Metrics/AbcSize
32
38
 
33
39
  private
34
40
 
@@ -44,31 +50,21 @@ module ChainedJob
44
50
  }
45
51
  end
46
52
 
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
+ def job_tag
54
+ @job_tag ||= Time.now.to_f.to_s
53
55
  end
54
56
 
55
57
  def log_chained_job_start
56
58
  ChainedJob.logger.info(
57
- "#{job_class} starting #{parallelism} workers "\
59
+ "#{job_class}:#{job_tag} starting #{parallelism} workers "\
58
60
  "processing #{array_of_job_arguments.count} items"
59
61
  )
60
62
  end
61
63
 
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
64
+ def log_chained_job_cleanup
65
+ ChainedJob.logger.info(
66
+ "#{job_class}:#{job_tag} cleanup"
67
+ )
72
68
  end
73
69
  end
74
70
  end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'chained_job/helpers'
4
+
5
+ module ChainedJob
6
+ class StoreJobArguments
7
+ def self.run(job_class, job_tag, array_of_job_arguments)
8
+ new(job_class, job_tag, array_of_job_arguments).run
9
+ end
10
+
11
+ attr_reader :job_class, :job_tag, :array_of_job_arguments
12
+
13
+ def initialize(job_class, job_tag, array_of_job_arguments)
14
+ @job_class = job_class
15
+ @job_tag = job_tag
16
+ @array_of_job_arguments = array_of_job_arguments
17
+ end
18
+
19
+ def run
20
+ set_tag_list
21
+
22
+ array_of_job_arguments.each_slice(config.arguments_batch_size) do |sublist|
23
+ ChainedJob.redis.rpush(redis_key, sublist)
24
+ end
25
+
26
+ ChainedJob.redis.expire(redis_key, config.arguments_queue_expiration)
27
+ end
28
+
29
+ private
30
+
31
+ def set_tag_list
32
+ ChainedJob.redis.sadd(tag_list, job_tag)
33
+ end
34
+
35
+ def tag_list
36
+ Helpers.tag_list(job_key)
37
+ end
38
+
39
+ def redis_key
40
+ @redis_key ||= Helpers.redis_key(job_key, job_tag)
41
+ end
42
+
43
+ def job_key
44
+ @job_key ||= Helpers.job_key(job_class)
45
+ end
46
+
47
+ def config
48
+ ChainedJob.config
49
+ end
50
+ end
51
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ChainedJob
4
- VERSION = '0.1.2'
4
+ VERSION = '0.4.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chained_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mantas Kūjalis
@@ -9,22 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-04-29 00:00:00.000000000 Z
12
+ date: 2021-04-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: '1.17'
20
+ version: '0'
21
21
  type: :development
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - "~>"
25
+ - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: '1.17'
27
+ version: '0'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: minitest
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -53,35 +53,22 @@ dependencies:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
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
56
  description: Chained job allows you to define an array of queued jobs that should
71
57
  be run in sequence after the main job has been executed successfully.
72
58
  email:
73
- - mantas.kujalis@vinted.com
74
- - titas@vinted.com
59
+ - backend@vinted.com
75
60
  executables: []
76
61
  extensions: []
77
62
  extra_rdoc_files: []
78
63
  files:
79
64
  - lib/chained_job.rb
65
+ - lib/chained_job/clean_up_queue.rb
80
66
  - lib/chained_job/config.rb
81
67
  - lib/chained_job/helpers.rb
82
68
  - lib/chained_job/middleware.rb
83
69
  - lib/chained_job/process.rb
84
70
  - lib/chained_job/start_chains.rb
71
+ - lib/chained_job/store_job_arguments.rb
85
72
  - lib/chained_job/version.rb
86
73
  homepage: https://github.com/vinted/chained_job
87
74
  licenses:
@@ -102,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
89
  - !ruby/object:Gem::Version
103
90
  version: '0'
104
91
  requirements: []
105
- rubygems_version: 3.0.3
92
+ rubygems_version: 3.1.4
106
93
  signing_key:
107
94
  specification_version: 4
108
95
  summary: Chained job helper