sidekiq-hierarchy 1.1.0 → 2.0.0

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
  SHA1:
3
- metadata.gz: 7bbc58dd27887b22cd4028b50d0baa627155c604
4
- data.tar.gz: a19dd469928472862f286c9408471b898f30f839
3
+ metadata.gz: 7da49b3d427ff6aad77da49fbf6aedcbaf9ba70b
4
+ data.tar.gz: 9ac4dcc0972bba86b7d251ef73be6297fc19627b
5
5
  SHA512:
6
- metadata.gz: cadcdc2e2ab393ecae67ea16f8cc7a609df3e00f30e43b1d144f8dd1706f141646156708afd17ddfb37b54b75235987c4cdf45f55226e29ec36c1cdb18d248a0
7
- data.tar.gz: 37e3e7654896e53377e4b462f76282dafabaa8967fb22827c4d1c0df08fc9bd8b023cf555c40933c238ea56a905bdea7cfc1c29480382f035b7b8636edb39839
6
+ metadata.gz: 61442fd3a766b589dcaed9570320e7aebddbc7b695ad1ef7e65dba6b0f976c0441b752dd19104e76aa99c646445dc23b0482954a5ac0ee692e438bfb185cb9ce
7
+ data.tar.gz: 6f7b1463ba5e4d27fcff502a7136b7ddec1c8b82e4605fd8767f9bea681fe3b9ab4069f6224c313a5c93ad963f0b1af06ef063a315af39481ff562365cef2a28
data/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
+ ## [2.0.0] - 2015-12-04
6
+ ### Changed
7
+ - HTTP headers renamed to make roles more clear
8
+ - Thread locals renamed to make collisions less likely
9
+
10
+ ### Added
11
+ - Track workflow timings directly to avoid iteration
12
+ - Record per-subtree job counts and finished job counts
13
+ - Add subtree iteration
14
+
15
+
5
16
  ## [1.1.0] - 2015-12-04
6
17
  ### Changed
7
18
  - Use Sinatra template helpers to get template caching for views
data/README.md CHANGED
@@ -107,11 +107,17 @@ Some examples to try, given a root `JID`:
107
107
  => [2015-11-11 15:00:42 -0800, 2015-11-11 15:00:42 -0800, 2015-11-11 15:01:32 -0800]
108
108
  ```
109
109
  ```ruby
110
+ > workflow.job_count # stored value, no iteration necessary
111
+ => 33
112
+
110
113
  > workflow.jobs.count # lazily eval'd
111
114
  => 33
112
115
 
113
116
  > workflow.jobs.map(&:jid)
114
117
  => ["11c3ec3df251ebb646f910d7", "f003db430a0eae99d72f1b7a", "bc2cf8f3de3b87f9a4c3c10e", ...]
118
+
119
+ > workflow.finished_job_count
120
+ => 33
115
121
  ```
116
122
  ```ruby
117
123
  > root_job = workflow.root
@@ -176,7 +182,7 @@ Explore the classes to learn more you can access, including:
176
182
  - timestamps for all status changes (`#enqueued_at`, `#run_at`, etc.)
177
183
  - tree exploration (`#root`, `#parent`, `#children`, `#leaf?`, etc.)
178
184
  - lazy enumerators over jobs and workflows (`Workflow#jobs`, `WorkflowSet#each`)
179
- - current workflow and job id context (`Sidekiq::Hierarchy.current_workflow`, `.current_jid`)
185
+ - current workflow and job context (`Sidekiq::Hierarchy.current_workflow`, `.current_job`)
180
186
 
181
187
  Each `Workflow` can be treated as a Redis-backed hash (all values will be coerced to strings). Combined with the fact that the current workflow context can always be accessed via `Sidekiq::Hierarchy.current_workflow` (nil if not in a workflow), you can pass arbitrary information through a work tree.
182
188
 
@@ -276,7 +282,7 @@ end
276
282
 
277
283
  In the background, Sidekiq-hierarchy inserts and decodes two headers:
278
284
 
279
- - Sidekiq-Jid: the job id of the parent worker, if any
285
+ - Sidekiq-Job: the job id of the parent worker, if any
280
286
  - Sidekiq-Workflow: the workflow JID, if tracking is enabled (`workflow: true` in sidekiq_options)
281
287
 
282
288
  Even if you are not using Faraday, adding these headers should be easy with your network library of choice.
@@ -340,14 +346,14 @@ On the server side, _inside_ the hierarchy middleware to ensure variables are se
340
346
  ```ruby
341
347
  class FailFast::ServerMiddleware
342
348
  def call(worker, job, queue)
343
- current_jid = Sidekiq::Hierarchy.current_jid
349
+ current_job = Sidekiq::Hierarchy.current_job
344
350
  workflow = Sidekiq::Hierarchy.current_workflow
345
351
  return if workflow && workflow[:fail_fast]
346
352
 
347
353
  yield
348
354
 
349
355
  rescue => e
350
- if workflow && Sidekiq::Hierarchy::Job.find(current_jid).failed?
356
+ if workflow && current_job.failed?
351
357
  workflow[:fail_fast] = '1'
352
358
  end
353
359
  raise # make sure to propagate exception up
@@ -34,22 +34,22 @@ module Sidekiq
34
34
 
35
35
  # Sets the workflow object for the current fiber/worker
36
36
  def current_workflow=(workflow)
37
- Thread.current[:workflow] = workflow
37
+ Thread.current[:sidekiq_hierarchy_workflow] = workflow
38
38
  end
39
39
 
40
40
  # Retrieves the current Sidekiq workflow if previously set
41
41
  def current_workflow
42
- Thread.current[:workflow]
42
+ Thread.current[:sidekiq_hierarchy_workflow]
43
43
  end
44
44
 
45
- # Sets the jid for the current fiber/worker
46
- def current_jid=(jid)
47
- Thread.current[:jid] = jid
45
+ # Sets the job for the current fiber/worker
46
+ def current_job=(job)
47
+ Thread.current[:sidekiq_hierarchy_job] = job
48
48
  end
49
49
 
50
- # Retrieves jid for the current Sidekiq job if previously set
51
- def current_jid
52
- Thread.current[:jid]
50
+ # Retrieves job for the current Sidekiq job if previously set
51
+ def current_job
52
+ Thread.current[:sidekiq_hierarchy_job]
53
53
  end
54
54
 
55
55
 
@@ -57,15 +57,14 @@ module Sidekiq
57
57
 
58
58
  def record_job_enqueued(job)
59
59
  return unless !!job['workflow']
60
- if current_jid.nil?
60
+ if current_job.nil?
61
61
  # this is a root-level job, i.e., start of a workflow
62
62
  queued_job = Job.create(job['jid'], job)
63
63
  queued_job.enqueue! # initial status: enqueued
64
- elsif current_jid == job['jid']
64
+ elsif current_job.jid == job['jid']
65
65
  # this is a job requeuing itself, ignore it
66
66
  else
67
67
  # this is an intermediate job, having both parent and children
68
- current_job = Job.find(current_jid)
69
68
  queued_job = Job.create(job['jid'], job)
70
69
  current_job.add_child(queued_job)
71
70
  queued_job.enqueue! # initial status: enqueued
@@ -73,23 +72,23 @@ module Sidekiq
73
72
  end
74
73
 
75
74
  def record_job_running
76
- return unless enabled? && current_jid
77
- Job.find(current_jid).run!
75
+ return unless enabled? && current_job
76
+ current_job.run!
78
77
  end
79
78
 
80
79
  def record_job_complete
81
- return unless enabled? && current_jid
82
- Job.find(current_jid).complete!
80
+ return unless enabled? && current_job
81
+ current_job.complete!
83
82
  end
84
83
 
85
84
  def record_job_requeued
86
- return unless enabled? && current_jid
87
- Job.find(current_jid).requeue!
85
+ return unless enabled? && current_job
86
+ current_job.requeue!
88
87
  end
89
88
 
90
89
  def record_job_failed
91
- return unless enabled? && current_jid
92
- Job.find(current_jid).fail!
90
+ return unless enabled? && current_job
91
+ current_job.fail!
93
92
  end
94
93
 
95
94
 
@@ -6,8 +6,8 @@ module Sidekiq
6
6
  module Faraday
7
7
  class Middleware < ::Faraday::Middleware
8
8
  def call(env)
9
- if Sidekiq::Hierarchy.current_workflow && Sidekiq::Hierarchy.current_jid
10
- env[:request_headers][Sidekiq::Hierarchy::Http::JID_HEADER] = Sidekiq::Hierarchy.current_jid
9
+ if Sidekiq::Hierarchy.current_workflow && Sidekiq::Hierarchy.current_job
10
+ env[:request_headers][Sidekiq::Hierarchy::Http::JOB_HEADER] = Sidekiq::Hierarchy.current_job.jid
11
11
  env[:request_headers][Sidekiq::Hierarchy::Http::WORKFLOW_HEADER] = Sidekiq::Hierarchy.current_workflow.jid
12
12
  end
13
13
  @app.call(env)
@@ -1,7 +1,7 @@
1
1
  module Sidekiq
2
2
  module Hierarchy
3
3
  module Http
4
- JID_HEADER = 'Sidekiq-Jid'.freeze
4
+ JOB_HEADER = 'Sidekiq-Job'.freeze
5
5
  WORKFLOW_HEADER = 'Sidekiq-Workflow'.freeze
6
6
  end
7
7
  end
@@ -7,11 +7,16 @@ module Sidekiq
7
7
  INFO_FIELD = 'i'.freeze
8
8
  PARENT_FIELD = 'p'.freeze
9
9
  STATUS_FIELD = 's'.freeze
10
- WORKFLOW_STATUS_FIELD = 'w'.freeze
10
+
11
11
  ENQUEUED_AT_FIELD = 'e'.freeze
12
12
  RUN_AT_FIELD = 'r'.freeze
13
13
  COMPLETED_AT_FIELD = 'c'.freeze
14
14
 
15
+ WORKFLOW_STATUS_FIELD = 'w'.freeze
16
+ WORKFLOW_FINISHED_AT_FIELD = 'wf'.freeze
17
+ SUBTREE_SIZE_FIELD = 't'.freeze
18
+ FINISHED_SUBTREE_SIZE_FIELD = 'tf'.freeze
19
+
15
20
  # Values for STATUS_FIELD
16
21
  STATUS_ENQUEUED = '0'.freeze
17
22
  STATUS_RUNNING = '1'.freeze
@@ -37,6 +42,7 @@ module Sidekiq
37
42
  def create(jid, job_hash)
38
43
  new(jid).tap do |job|
39
44
  job[INFO_FIELD] = Sidekiq.dump_json(filtered_job_hash(job_hash))
45
+ job.increment_subtree_size # start at subtree size 1 -- no children
40
46
  end
41
47
  end
42
48
 
@@ -121,6 +127,44 @@ module Sidekiq
121
127
  self.leaf? ? [self] : children.flat_map(&:leaves)
122
128
  end
123
129
 
130
+ # Walks the subtree rooted here in DFS order
131
+ # Returns an Enumerator; use #to_a to get an array instead
132
+ def subtree_jobs
133
+ to_visit = [self]
134
+ Enumerator.new do |y|
135
+ while node = to_visit.pop
136
+ y << node # sugar for yielding a value
137
+ to_visit += node.children
138
+ end
139
+ end
140
+ end
141
+
142
+ # The cached cardinality of the tree rooted at this job
143
+ def subtree_size
144
+ self[SUBTREE_SIZE_FIELD].to_i
145
+ end
146
+
147
+ # Recursively updates subtree size on this and all higher subtrees
148
+ def increment_subtree_size(incr=1)
149
+ redis { |conn| conn.hincrby(redis_job_hkey, SUBTREE_SIZE_FIELD, incr) }
150
+ if p_job = parent
151
+ p_job.increment_subtree_size(incr)
152
+ end
153
+ end
154
+
155
+ # The cached count of the finished jobs in the tree rooted at this job
156
+ def finished_subtree_size
157
+ self[FINISHED_SUBTREE_SIZE_FIELD].to_i
158
+ end
159
+
160
+ # Recursively updates finished subtree size on this and all higher subtrees
161
+ def increment_finished_subtree_size(incr=1)
162
+ redis { |conn| conn.hincrby(redis_job_hkey, FINISHED_SUBTREE_SIZE_FIELD, incr) }
163
+ if p_job = parent
164
+ p_job.increment_finished_subtree_size(incr)
165
+ end
166
+ end
167
+
124
168
  # Draws a new doubly-linked parent-child relationship in redis
125
169
  def add_child(child_job)
126
170
  redis do |conn|
@@ -133,7 +177,10 @@ module Sidekiq
133
177
  conn.expire(redis_children_lkey, ONE_MONTH)
134
178
  end
135
179
  end
136
- true # will never fail w/o raising an exception
180
+
181
+ # updates subtree counts to reflect new child
182
+ increment_subtree_size(child_job.subtree_size)
183
+ increment_finished_subtree_size(child_job.finished_subtree_size)
137
184
  end
138
185
 
139
186
  def workflow
@@ -179,6 +226,7 @@ module Sidekiq
179
226
 
180
227
  self[STATUS_FIELD] = s_val
181
228
  self[t_field] = Time.now.to_f.to_s if t_field
229
+ increment_finished_subtree_size if [:failed, :complete].include?(new_status)
182
230
 
183
231
  Sidekiq::Hierarchy.publish(Notifications::JOB_UPDATE, self, new_status, old_status)
184
232
  end
@@ -250,6 +298,10 @@ module Sidekiq
250
298
  end
251
299
  end
252
300
 
301
+ def finished?
302
+ [:failed, :complete].include?(status) # two terminal states
303
+ end
304
+
253
305
  def finished_at
254
306
  if t = self[COMPLETED_AT_FIELD]
255
307
  Time.at(t.to_f)
@@ -6,7 +6,7 @@ module Sidekiq
6
6
  module Rack
7
7
  class Middleware
8
8
  # transform from http header to rack names
9
- JID_HEADER_KEY = "HTTP_#{Sidekiq::Hierarchy::Http::JID_HEADER.upcase.gsub('-','_')}".freeze
9
+ JOB_HEADER_KEY = "HTTP_#{Sidekiq::Hierarchy::Http::JOB_HEADER.upcase.gsub('-','_')}".freeze
10
10
  WORKFLOW_HEADER_KEY = "HTTP_#{Sidekiq::Hierarchy::Http::WORKFLOW_HEADER.upcase.gsub('-','_')}".freeze
11
11
 
12
12
  def initialize(app)
@@ -14,14 +14,14 @@ module Sidekiq
14
14
  end
15
15
 
16
16
  def call(env)
17
- if env[WORKFLOW_HEADER_KEY] && env[JID_HEADER_KEY]
18
- Sidekiq::Hierarchy.current_jid = env[JID_HEADER_KEY]
17
+ if env[WORKFLOW_HEADER_KEY] && env[JOB_HEADER_KEY]
18
+ Sidekiq::Hierarchy.current_job = Job.find(env[JOB_HEADER_KEY])
19
19
  Sidekiq::Hierarchy.current_workflow = Workflow.find_by_jid(env[WORKFLOW_HEADER_KEY])
20
20
  end
21
21
  @app.call(env)
22
22
  ensure
23
23
  Sidekiq::Hierarchy.current_workflow = nil
24
- Sidekiq::Hierarchy.current_jid = nil
24
+ Sidekiq::Hierarchy.current_job = nil
25
25
  end
26
26
  end
27
27
  end
@@ -14,10 +14,10 @@ module Sidekiq
14
14
  def call(worker, msg, queue)
15
15
  if msg['workflow'] == true # root job -- start of a new workflow
16
16
  Sidekiq::Hierarchy.current_workflow = Workflow.find_by_jid(worker.jid)
17
- Sidekiq::Hierarchy.current_jid = worker.jid
17
+ Sidekiq::Hierarchy.current_job = Sidekiq::Hierarchy.current_workflow.root
18
18
  elsif msg['workflow'].is_a?(String) # child job -- inherit parent's workflow
19
19
  Sidekiq::Hierarchy.current_workflow = Workflow.find_by_jid(msg['workflow'])
20
- Sidekiq::Hierarchy.current_jid = worker.jid
20
+ Sidekiq::Hierarchy.current_job = Job.find(worker.jid)
21
21
  end
22
22
 
23
23
  Sidekiq::Hierarchy.record_job_running
@@ -1,5 +1,5 @@
1
1
  module Sidekiq
2
2
  module Hierarchy
3
- VERSION = '1.1.0'
3
+ VERSION = '2.0.0'
4
4
  end
5
5
  end
@@ -28,6 +28,10 @@ module Sidekiq
28
28
  "#{root_path}hierarchy/workflow_sets/#{status}"
29
29
  end
30
30
 
31
+ def safe_relative_time(timestamp)
32
+ timestamp.nil? ? '-' : relative_time(timestamp)
33
+ end
34
+
31
35
  def status_updated_at(job)
32
36
  case job.status
33
37
  when :enqueued
@@ -34,18 +34,9 @@ module Sidekiq
34
34
  wset.remove(self) if wset # now we can clear out from the set
35
35
  end
36
36
 
37
- # Walks the tree in DFS order (for optimal completion checking)
38
- # Returns an Enumerator; use #to_a to get an array instead
39
- def jobs
40
- to_visit = [root]
41
- Enumerator.new do |y|
42
- while node = to_visit.pop
43
- y << node # sugar for yielding a value
44
- to_visit += node.children
45
- end
46
- end
47
- end
48
-
37
+ def_delegator :@root, :subtree_jobs, :jobs
38
+ def_delegator :@root, :subtree_size, :job_count
39
+ def_delegator :@root, :finished_subtree_size, :finished_job_count
49
40
 
50
41
  ### Status
51
42
 
@@ -70,12 +61,13 @@ module Sidekiq
70
61
  new_status, s_val = :running, Job::STATUS_RUNNING
71
62
  elsif from_job_status == :failed
72
63
  new_status, s_val = :failed, Job::STATUS_FAILED
73
- elsif from_job_status == :complete && jobs.all?(&:complete?)
64
+ elsif from_job_status == :complete && root.subtree_size == root.finished_subtree_size
74
65
  new_status, s_val = :complete, Job::STATUS_COMPLETE
75
66
  end
76
-
77
67
  return if !new_status || new_status == old_status # don't publish null updates
68
+
78
69
  self[Job::WORKFLOW_STATUS_FIELD] = s_val
70
+ self[Job::WORKFLOW_FINISHED_AT_FIELD] = Time.now.to_f.to_s if [:failed, :complete].include?(new_status)
79
71
 
80
72
  Sidekiq::Hierarchy.publish(Notifications::WORKFLOW_UPDATE, self, new_status, old_status)
81
73
  end
@@ -106,21 +98,25 @@ module Sidekiq
106
98
  # Returns the time at which all jobs were complete;
107
99
  # nil if any jobs are still incomplete
108
100
  def complete_at
109
- jobs.map(&:complete_at).max if complete?
101
+ Time.at(self[Job::WORKFLOW_FINISHED_AT_FIELD].to_f) if complete?
110
102
  end
111
103
 
112
104
  # Returns the earliest time at which a job failed;
113
105
  # nil if none did
114
106
  def failed_at
115
- jobs.map(&:failed_at).compact.min if failed?
107
+ Time.at(self[Job::WORKFLOW_FINISHED_AT_FIELD].to_f) if failed?
108
+ end
109
+
110
+ def finished_at
111
+ if timestamp = self[Job::WORKFLOW_FINISHED_AT_FIELD]
112
+ Time.at(timestamp.to_f)
113
+ end
116
114
  end
117
115
 
118
116
 
119
117
  ### Serialisation
120
118
 
121
- def as_json(options={})
122
- root.as_json(options)
123
- end
119
+ delegate :as_json => :@root
124
120
 
125
121
  def to_s
126
122
  Sidekiq.dump_json(self.as_json)
@@ -8,7 +8,7 @@
8
8
  <th>Run at</th>
9
9
  <th>Completed at</th>
10
10
  <th>Failed at</th>
11
- <th>Jobs</th>
11
+ <th>Completion</th>
12
12
  </tr>
13
13
  </thead>
14
14
 
@@ -25,7 +25,7 @@
25
25
  <td><%= workflow.run_at %></td>
26
26
  <td><%= workflow.complete_at %></td>
27
27
  <td><%= workflow.failed_at %></td>
28
- <td><%= workflow.jobs.count %></td>
28
+ <td><%= workflow.finished_job_count %>/<%= workflow.job_count %></td>
29
29
  </tr>
30
30
  <% end%>
31
31
  </tbody>
@@ -5,12 +5,14 @@
5
5
  </span>
6
6
  (<%= job.info['queue'] %>)
7
7
  <span class="label label-<%= bootstrap_status(job.status) %>">
8
- <%= job.status %> <%= relative_time(status_updated_at(job)) %>
8
+ <%= job.status %> <%= safe_relative_time(status_updated_at(job)) %>
9
9
  </span>
10
10
  </a>
11
- <% unless job.leaf? %>
11
+
12
+ <%- children = job.children %>
13
+ <% if children.any? %>
12
14
  <ul>
13
- <% job.children.each do |child| %>
15
+ <% children.each do |child| %>
14
16
  <%= erb :_workflow_tree_node, locals: {job: child} %>
15
17
  <% end %>
16
18
  </ul>
data/web/views/status.erb CHANGED
@@ -19,6 +19,7 @@
19
19
  <th>Workflow ID</th>
20
20
  <th>Enqueued at</th>
21
21
  <th>Run at</th>
22
+ <th>Completion</th>
22
23
  </tr>
23
24
  </thead>
24
25
 
@@ -30,8 +31,9 @@
30
31
  <%= workflow.jid %>
31
32
  </a>
32
33
  </td>
33
- <td><%= relative_time(workflow.enqueued_at) %></td>
34
- <td><%= relative_time(workflow.run_at) if workflow.run_at %></td>
34
+ <td><%= safe_relative_time(workflow.enqueued_at) %></td>
35
+ <td><%= safe_relative_time(workflow.run_at) if workflow.run_at %></td>
36
+ <td><%= workflow.finished_job_count %>/<%= workflow.job_count %></td>
35
37
  </tr>
36
38
  <% end%>
37
39
  </tbody>
@@ -57,6 +59,7 @@
57
59
  <th>Enqueued at</th>
58
60
  <th>Run at</th>
59
61
  <th>Completed at</th>
62
+ <th>Job count</th>
60
63
  </tr>
61
64
  </thead>
62
65
 
@@ -68,9 +71,10 @@
68
71
  <%= workflow.jid %>
69
72
  </a>
70
73
  </td>
71
- <td><%= relative_time(workflow.enqueued_at) %></td>
72
- <td><%= relative_time(workflow.run_at) %></td>
73
- <td><%= relative_time(workflow.complete_at) %></td>
74
+ <td><%= safe_relative_time(workflow.enqueued_at) %></td>
75
+ <td><%= safe_relative_time(workflow.run_at) %></td>
76
+ <td><%= safe_relative_time(workflow.complete_at) %></td>
77
+ <td><%= workflow.job_count %></td>
74
78
  </tr>
75
79
  <% end%>
76
80
  </tbody>
@@ -98,6 +102,7 @@
98
102
  <th>Enqueued at</th>
99
103
  <th>Run at</th>
100
104
  <th>Failed at</th>
105
+ <th>Job count</th>
101
106
  </tr>
102
107
  </thead>
103
108
 
@@ -109,9 +114,10 @@
109
114
  <%= workflow.jid %>
110
115
  </a>
111
116
  </td>
112
- <td><%= relative_time(workflow.enqueued_at) %></td>
113
- <td><%= relative_time(workflow.run_at) %></td>
114
- <td><%= relative_time(workflow.failed_at) %></td>
117
+ <td><%= safe_relative_time(workflow.enqueued_at) %></td>
118
+ <td><%= safe_relative_time(workflow.run_at) %></td>
119
+ <td><%= safe_relative_time(workflow.failed_at) %></td>
120
+ <td><%= workflow.job_count %></td>
115
121
  </tr>
116
122
  <% end %>
117
123
  </tbody>
@@ -11,6 +11,7 @@
11
11
  <th>Run at</th>
12
12
  <th>Completed at</th>
13
13
  <th>Failed at</th>
14
+ <th>Completion</th>
14
15
  </tr>
15
16
  </thead>
16
17
 
@@ -21,6 +22,7 @@
21
22
  <td><%= @workflow.run_at %></td>
22
23
  <td><%= @workflow.complete_at %></td>
23
24
  <td><%= @workflow.failed_at %></td>
25
+ <td><%= @workflow.finished_job_count %>/<%= @workflow.job_count %></td>
24
26
  </tr>
25
27
  </tbody>
26
28
  </table>
metadata CHANGED
@@ -1,167 +1,168 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-hierarchy
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anuj Das
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
11
  date: 2015-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
+ name: sidekiq
14
15
  requirement: !ruby/object:Gem::Requirement
15
16
  requirements:
16
- - - ~>
17
+ - - "~>"
17
18
  - !ruby/object:Gem::Version
18
19
  version: '3.3'
19
- name: sidekiq
20
- prerelease: false
21
20
  type: :runtime
21
+ prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3.3'
27
27
  - !ruby/object:Gem::Dependency
28
+ name: connection_pool
28
29
  requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ~>
31
+ - - "~>"
31
32
  - !ruby/object:Gem::Version
32
33
  version: '2.0'
33
- name: connection_pool
34
- prerelease: false
35
34
  type: :runtime
35
+ prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.0'
41
41
  - !ruby/object:Gem::Dependency
42
+ name: bundler
42
43
  requirement: !ruby/object:Gem::Requirement
43
44
  requirements:
44
- - - ~>
45
+ - - "~>"
45
46
  - !ruby/object:Gem::Version
46
47
  version: '1.10'
47
- name: bundler
48
- prerelease: false
49
48
  type: :development
49
+ prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.10'
55
55
  - !ruby/object:Gem::Dependency
56
+ name: rake
56
57
  requirement: !ruby/object:Gem::Requirement
57
58
  requirements:
58
- - - ~>
59
+ - - "~>"
59
60
  - !ruby/object:Gem::Version
60
61
  version: '10.0'
61
- name: rake
62
- prerelease: false
63
62
  type: :development
63
+ prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '10.0'
69
69
  - !ruby/object:Gem::Dependency
70
+ name: rspec
70
71
  requirement: !ruby/object:Gem::Requirement
71
72
  requirements:
72
- - - ~>
73
+ - - "~>"
73
74
  - !ruby/object:Gem::Version
74
75
  version: '3.0'
75
- name: rspec
76
- prerelease: false
77
76
  type: :development
77
+ prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ~>
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.0'
83
83
  - !ruby/object:Gem::Dependency
84
+ name: rspec-its
84
85
  requirement: !ruby/object:Gem::Requirement
85
86
  requirements:
86
- - - '>='
87
+ - - ">="
87
88
  - !ruby/object:Gem::Version
88
89
  version: '0'
89
- name: rspec-its
90
- prerelease: false
91
90
  type: :development
91
+ prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
+ name: fakeredis
98
99
  requirement: !ruby/object:Gem::Requirement
99
100
  requirements:
100
- - - '>='
101
+ - - ">="
101
102
  - !ruby/object:Gem::Version
102
103
  version: '0'
103
- name: fakeredis
104
- prerelease: false
105
104
  type: :development
105
+ prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
+ name: rspec-sidekiq
112
113
  requirement: !ruby/object:Gem::Requirement
113
114
  requirements:
114
- - - '>='
115
+ - - ">="
115
116
  - !ruby/object:Gem::Version
116
117
  version: '0'
117
- name: rspec-sidekiq
118
- prerelease: false
119
118
  type: :development
119
+ prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
- - - '>='
122
+ - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
+ name: faraday
126
127
  requirement: !ruby/object:Gem::Requirement
127
128
  requirements:
128
- - - '>='
129
+ - - ">="
129
130
  - !ruby/object:Gem::Version
130
131
  version: '0'
131
- name: faraday
132
- prerelease: false
133
132
  type: :development
133
+ prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
- - - '>='
136
+ - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
+ name: rack
140
141
  requirement: !ruby/object:Gem::Requirement
141
142
  requirements:
142
- - - '>='
143
+ - - ">="
143
144
  - !ruby/object:Gem::Version
144
145
  version: '0'
145
- name: rack
146
- prerelease: false
147
146
  type: :development
147
+ prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - '>='
150
+ - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
- description: A set of sidekiq middlewares to track workflows consisting of multiple levels of sidekiq jobs
153
+ description: A set of sidekiq middlewares to track workflows consisting of multiple
154
+ levels of sidekiq jobs
154
155
  email:
155
156
  - anujdas@gmail.com
156
157
  executables: []
157
158
  extensions: []
158
159
  extra_rdoc_files: []
159
160
  files:
160
- - .gitignore
161
- - .rspec
162
- - .ruby-gemset
163
- - .ruby-version
164
- - .travis.yml
161
+ - ".gitignore"
162
+ - ".rspec"
163
+ - ".ruby-gemset"
164
+ - ".ruby-version"
165
+ - ".travis.yml"
165
166
  - CHANGELOG.md
166
167
  - CONTRIBUTING.md
167
168
  - Gemfile
@@ -215,24 +216,25 @@ homepage: https://www.github.com/anujdas/sidekiq-hierarchy
215
216
  licenses:
216
217
  - MIT
217
218
  metadata: {}
218
- post_install_message:
219
+ post_install_message:
219
220
  rdoc_options: []
220
221
  require_paths:
221
222
  - lib
222
223
  required_ruby_version: !ruby/object:Gem::Requirement
223
224
  requirements:
224
- - - '>='
225
+ - - ">="
225
226
  - !ruby/object:Gem::Version
226
227
  version: '0'
227
228
  required_rubygems_version: !ruby/object:Gem::Requirement
228
229
  requirements:
229
- - - '>='
230
+ - - ">="
230
231
  - !ruby/object:Gem::Version
231
232
  version: '0'
232
233
  requirements: []
233
- rubyforge_project:
234
- rubygems_version: 2.4.8
235
- signing_key:
234
+ rubyforge_project:
235
+ rubygems_version: 2.4.5.1
236
+ signing_key:
236
237
  specification_version: 4
237
- summary: A set of sidekiq middlewares to track workflows consisting of multiple levels of sidekiq jobs
238
+ summary: A set of sidekiq middlewares to track workflows consisting of multiple levels
239
+ of sidekiq jobs
238
240
  test_files: []