chained_job 0.1.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7a8aa04f7ae42cb12af32784e969ce63952884ff5db3e6e435943bcf1112f50b
4
- data.tar.gz: db0cc9308feec6d98a8d8444f7c96da901b204f14d265cc1f6b20df9eab6a72a
3
+ metadata.gz: b302104a73850add4edc180a181961885c7c5a5c8bc520fc26b3dfa1a82c6d39
4
+ data.tar.gz: 25c67ef1d56381c0704ef70e182937412c120ff995b01ef6036e2fd840f5ab29
5
5
  SHA512:
6
- metadata.gz: b865a3f752707bea1255f0bbc76bbb29ed901ab83b05092ef4c03274651d7b0eadee5307f6f28610a0cbfe374ede0e141a482c837b9677ed2defb52923b03190
7
- data.tar.gz: 6b3b01a064ed9a76948196c16715c24226382c6fed5925a5fa3f53455a0b6b7d7976a066721de58746b0cb1bf6d3ed28899dd97901bfbf510f28b38f40a033dd
6
+ metadata.gz: 46c772e243c573a1cb4dd16b21d2cd34127665e174eab7c90946dd3065941f509b35a05b5c6fb498f634f5b03d4b926ccd3747626f66fbe2591f53423ace47a3
7
+ data.tar.gz: fc1881df18aa578066ca959c22e21617dc089b0a7615fc4c340c501bb06a35e52e99f587084b50729e6ab3c62b7aafb6bec7e60de4a2663968423db88b267fc9
@@ -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,11 @@ module ChainedJob
12
12
  :arguments_queue_expiration,
13
13
  :around_start_chains,
14
14
  :around_chain_process,
15
+ :around_array_of_job_arguments,
15
16
  :debug,
16
17
  :logger,
17
18
  :redis,
19
+ :queue,
18
20
  )
19
21
 
20
22
  def initialize
@@ -25,6 +27,7 @@ module ChainedJob
25
27
 
26
28
  self.around_start_chains = ->(_options, &block) { block.call }
27
29
  self.around_chain_process = ->(_options, &block) { block.call }
30
+ self.around_array_of_job_arguments = ->(_options, &block) { block.call }
28
31
 
29
32
  self.debug = true
30
33
  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,15 +4,16 @@ 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
@@ -20,7 +21,7 @@ module ChainedJob
20
21
  return log_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
 
@@ -36,7 +37,7 @@ module ChainedJob
36
37
 
37
38
  def log_finished_worker
38
39
  ChainedJob.logger.info(
39
- "#{job_instance.class} worker #{worker_id} finished"
40
+ "#{job_instance.class}:#{job_tag} worker #{worker_id} finished"
40
41
  )
41
42
  end
42
43
 
@@ -45,7 +46,11 @@ module ChainedJob
45
46
  end
46
47
 
47
48
  def redis_key
48
- Helpers.redis_key(job_instance.class)
49
+ Helpers.redis_key(job_key, job_tag)
50
+ end
51
+
52
+ def job_key
53
+ Helpers.job_key(job_instance.class)
49
54
  end
50
55
  end
51
56
  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
22
25
 
23
- return unless array_of_job_arguments.count.positive?
26
+ ChainedJob::CleanUpQueue.run(job_class)
24
27
 
25
- store_job_arguments
28
+ next unless array_of_job_arguments.count.positive?
29
+
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.0'
4
+ VERSION = '0.3.0'
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.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mantas Kūjalis
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-04-24 00:00:00.000000000 Z
12
+ date: 2020-10-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -72,20 +72,18 @@ description: Chained job allows you to define an array of queued jobs that shoul
72
72
  email:
73
73
  - mantas.kujalis@vinted.com
74
74
  - titas@vinted.com
75
- executables:
76
- - setup
77
- - console
75
+ executables: []
78
76
  extensions: []
79
77
  extra_rdoc_files: []
80
78
  files:
81
- - bin/console
82
- - bin/setup
83
79
  - lib/chained_job.rb
80
+ - lib/chained_job/clean_up_queue.rb
84
81
  - lib/chained_job/config.rb
85
82
  - lib/chained_job/helpers.rb
86
83
  - lib/chained_job/middleware.rb
87
84
  - lib/chained_job/process.rb
88
85
  - lib/chained_job/start_chains.rb
86
+ - lib/chained_job/store_job_arguments.rb
89
87
  - lib/chained_job/version.rb
90
88
  homepage: https://github.com/vinted/chained_job
91
89
  licenses:
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # frozen_string_literal: true
4
-
5
- require 'bundler/setup'
6
- require 'irb'
7
-
8
- require 'chained_job'
9
-
10
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here