specwrk 0.4.11 → 0.6.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 +4 -4
- data/CHANGELOG.md +28 -0
- data/README.md +1 -1
- data/lib/specwrk/cli.rb +7 -3
- data/lib/specwrk/cli_reporter.rb +16 -10
- data/lib/specwrk/client.rb +4 -2
- data/lib/specwrk/queue.rb +27 -11
- data/lib/specwrk/version.rb +1 -1
- data/lib/specwrk/web/app.rb +29 -4
- data/lib/specwrk/web/endpoints.rb +45 -32
- data/lib/specwrk/web.rb +9 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf78cf2d1c82bc0878e1e89777eb8de0ab04af441e210c64a15c2bad1277c1fa
|
4
|
+
data.tar.gz: 3701d6f676e4c31c3fb787f4ca59a8aaa7aa412118371470b069471da4e6c933
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: debda5ab7128ae03e74652196da8783b4d78ddf3648ccfd2c3e62104fe8a3fb87b98abbc68deb7d66565d66474a504a8d778ca0de44eef311e14188a4258f856
|
7
|
+
data.tar.gz: 1a4089b567a0840f91a133fef5580b6c5bd3c43190eb7cd1156fe3439e042f727b62bdf69ee1624815ac741f738907e43c92559be1f4c4d55268b2db1625b074
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## v0.4.11
|
4
|
+
|
5
|
+
- Move logic out of CLI methods ([#64](https://github.com/danielwestendorf/specwrk/issues/64)) by @danielwestendorf
|
6
|
+
- Add thruster in front of puma ([#65](https://github.com/danielwestendorf/specwrk/issues/65)) by @danielwestendorf
|
7
|
+
- Revise heartbeats logic ([#66](https://github.com/danielwestendorf/specwrk/issues/66)) by @danielwestendorf
|
8
|
+
|
9
|
+
## v0.4.9
|
10
|
+
|
11
|
+
- Remove single-run env var (it was not what I wanted) by @danielwestendorf
|
12
|
+
|
13
|
+
## v0.4.8
|
14
|
+
|
15
|
+
- Fix `config.ru` by @danielwestendorf
|
16
|
+
|
17
|
+
## v0.4.7
|
18
|
+
|
19
|
+
- Switch to Puma for the Docker image (#59) by @danielwestendorf
|
20
|
+
|
21
|
+
## v0.4.6
|
22
|
+
|
23
|
+
- Nil env var that will prevent start command from completing ([#56](https://github.com/danielwestendorf/specwrk/issues/56)) by @danielwestendorf
|
24
|
+
- Better handling of seed failing ([#57](https://github.com/danielwestendorf/specwrk/issues/57)) by @danielwestendorf
|
25
|
+
- Silence health logging ([#58](https://github.com/danielwestendorf/specwrk/issues/58)) by @danielwestendorf
|
26
|
+
- Add missing CCI caching of `report.json` ([#55](https://github.com/danielwestendorf/specwrk/issues/55)) by @danielwestendorf
|
27
|
+
- Add CircleCI examples ([#50](https://github.com/danielwestendorf/specwrk/issues/50)) by @danielwestendorf
|
28
|
+
- Better GHA Examples ([#49](https://github.com/danielwestendorf/specwrk/issues/49)) by @danielwestendorf
|
29
|
+
- Skip key lookup and rely on the result of `Hash#delete` instead by @danielwestendorf
|
30
|
+
|
3
31
|
## v0.4.5
|
4
32
|
|
5
33
|
- Set ENV var when generating seed examples [#47](https://github.com/danielwestendorf/specwrk/issues/47). by @danielwestendorf
|
data/README.md
CHANGED
@@ -129,7 +129,7 @@ Description:
|
|
129
129
|
Start one or more worker processes
|
130
130
|
|
131
131
|
Options:
|
132
|
-
--id=VALUE # The identifier for this worker.
|
132
|
+
--id=VALUE # The identifier for this worker. Overrides SPECWRK_ID. If none provided one in the format of specwrk-worker-8_RAND_CHARS-COUNT_INDEX will be used
|
133
133
|
--count=VALUE, -c VALUE # The number of worker processes you want to start, default: 1
|
134
134
|
--output=VALUE, -o VALUE # Directory where worker output is stored. Overrides SPECWRK_OUT, default: ".specwrk/"
|
135
135
|
--seed-waits=VALUE, -w VALUE # Number of times the worker will wait for examples to be seeded to the server. 1sec between attempts. Overrides SPECWRK_SEED_WAITS, default: "10"
|
data/lib/specwrk/cli.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "pathname"
|
4
|
+
require "securerandom"
|
4
5
|
|
5
6
|
require "dry/cli"
|
6
7
|
|
@@ -33,14 +34,15 @@ module Specwrk
|
|
33
34
|
extend Hookable
|
34
35
|
|
35
36
|
on_included do |base|
|
36
|
-
base.unique_option :id, type: :string,
|
37
|
+
base.unique_option :id, type: :string, desc: "The identifier for this worker. Overrides SPECWRK_ID. If none provided one in the format of specwrk-worker-8_RAND_CHARS-COUNT_INDEX will be used"
|
37
38
|
base.unique_option :count, type: :integer, default: 1, aliases: ["-c"], desc: "The number of worker processes you want to start"
|
38
39
|
base.unique_option :output, type: :string, default: ENV.fetch("SPECWRK_OUT", ".specwrk/"), aliases: ["-o"], desc: "Directory where worker output is stored. Overrides SPECWRK_OUT"
|
39
40
|
base.unique_option :seed_waits, type: :integer, default: ENV.fetch("SPECWRK_SEED_WAITS", "10"), aliases: ["-w"], desc: "Number of times the worker will wait for examples to be seeded to the server. 1sec between attempts. Overrides SPECWRK_SEED_WAITS"
|
40
41
|
end
|
41
42
|
|
42
|
-
on_setup do |
|
43
|
-
ENV["SPECWRK_ID"]
|
43
|
+
on_setup do |count:, output:, seed_waits:, id: "specwrk-worker-#{SecureRandom.uuid[0, 8]}", **|
|
44
|
+
ENV["SPECWRK_ID"] ||= id # Unique default. Don't override the ENV value here
|
45
|
+
|
44
46
|
ENV["SPECWRK_COUNT"] = count.to_s
|
45
47
|
ENV["SPECWRK_SEED_WAITS"] = seed_waits.to_s
|
46
48
|
ENV["SPECWRK_OUT"] = Pathname.new(output).expand_path(Dir.pwd).to_s
|
@@ -115,6 +117,8 @@ module Specwrk
|
|
115
117
|
|
116
118
|
Client.wait_for_server!
|
117
119
|
Client.new.seed(examples)
|
120
|
+
file_count = examples.group_by { |e| e[:file_path] }.keys.size
|
121
|
+
puts "🌱 Seeded #{examples.size} examples across #{file_count} files"
|
118
122
|
rescue Errno::ECONNREFUSED
|
119
123
|
puts "Server at #{ENV.fetch("SPECWRK_SRV_URI", "http://localhost:5138")} is refusing connections, exiting...#{ENV["SPECWRK_FLUSH_DELIMINATOR"]}"
|
120
124
|
exit 1
|
data/lib/specwrk/cli_reporter.rb
CHANGED
@@ -11,7 +11,10 @@ require "rspec/core/formatters/console_codes"
|
|
11
11
|
module Specwrk
|
12
12
|
class CLIReporter
|
13
13
|
def report
|
14
|
-
|
14
|
+
unless Client.connect?
|
15
|
+
puts colorizer.wrap("\nCannot connect to server to generate report. Assuming failure.", :red)
|
16
|
+
return 1
|
17
|
+
end
|
15
18
|
|
16
19
|
puts "\nFinished in #{total_duration} " \
|
17
20
|
"(total execution time of #{total_run_time})\n"
|
@@ -28,8 +31,11 @@ module Specwrk
|
|
28
31
|
puts colorizer.wrap(totals_line, :green)
|
29
32
|
0
|
30
33
|
end
|
31
|
-
rescue Specwrk::UnhandledResponseError
|
32
|
-
puts colorizer.wrap("
|
34
|
+
rescue Specwrk::UnhandledResponseError => e
|
35
|
+
puts colorizer.wrap("\nCannot report, #{e.message}.", :red)
|
36
|
+
|
37
|
+
client.shutdown
|
38
|
+
|
33
39
|
1
|
34
40
|
end
|
35
41
|
|
@@ -43,28 +49,28 @@ module Specwrk
|
|
43
49
|
summary
|
44
50
|
end
|
45
51
|
|
46
|
-
def
|
47
|
-
@
|
52
|
+
def report_data
|
53
|
+
@report_data ||= client.report
|
48
54
|
end
|
49
55
|
|
50
56
|
def total_duration
|
51
|
-
Time.parse(
|
57
|
+
Time.parse(report_data.dig(:meta, :last_finished_at)) - Time.parse(report_data.dig(:meta, :first_started_at))
|
52
58
|
end
|
53
59
|
|
54
60
|
def total_run_time
|
55
|
-
|
61
|
+
report_data.dig(:meta, :total_run_time)
|
56
62
|
end
|
57
63
|
|
58
64
|
def failure_count
|
59
|
-
|
65
|
+
report_data.dig(:meta, :failures)
|
60
66
|
end
|
61
67
|
|
62
68
|
def pending_count
|
63
|
-
|
69
|
+
report_data.dig(:meta, :pending)
|
64
70
|
end
|
65
71
|
|
66
72
|
def example_count
|
67
|
-
|
73
|
+
report_data.dig(:examples).length
|
68
74
|
end
|
69
75
|
|
70
76
|
def client
|
data/lib/specwrk/client.rb
CHANGED
@@ -62,8 +62,8 @@ module Specwrk
|
|
62
62
|
response.code == "200"
|
63
63
|
end
|
64
64
|
|
65
|
-
def
|
66
|
-
response = get "/
|
65
|
+
def report
|
66
|
+
response = get "/report"
|
67
67
|
|
68
68
|
if response.code == "200"
|
69
69
|
JSON.parse(response.body, symbolize_names: true)
|
@@ -150,7 +150,9 @@ module Specwrk
|
|
150
150
|
|
151
151
|
def default_headers
|
152
152
|
@default_headers ||= {}.tap do |h|
|
153
|
+
h["User-Agent"] = "Specwrk/#{VERSION}"
|
153
154
|
h["Authorization"] = "Bearer #{ENV["SPECWRK_SRV_KEY"]}" if ENV["SPECWRK_SRV_KEY"]
|
155
|
+
h["X-Specwrk-Id"] = ENV.fetch("SPECWRK_ID", "specwrk-client")
|
154
156
|
h["X-Specwrk-Run"] = ENV["SPECWRK_RUN"] if ENV["SPECWRK_RUN"]
|
155
157
|
h["Content-Type"] = "application/json"
|
156
158
|
end
|
data/lib/specwrk/queue.rb
CHANGED
@@ -6,7 +6,11 @@ require "json"
|
|
6
6
|
module Specwrk
|
7
7
|
# Thread-safe Hash access
|
8
8
|
class Queue
|
9
|
+
attr_reader :created_at
|
10
|
+
|
9
11
|
def initialize(hash = {})
|
12
|
+
@created_at = Time.now
|
13
|
+
|
10
14
|
if block_given?
|
11
15
|
@mutex = Monitor.new # Reentrant locking is required here
|
12
16
|
# It's possible to enter the proc from two threads, so we need to ||= in case
|
@@ -40,8 +44,6 @@ module Specwrk
|
|
40
44
|
end
|
41
45
|
|
42
46
|
class PendingQueue < Queue
|
43
|
-
attr_reader :previous_run_times
|
44
|
-
|
45
47
|
def shift_bucket
|
46
48
|
return bucket_by_file unless previous_run_times
|
47
49
|
|
@@ -59,17 +61,22 @@ module Specwrk
|
|
59
61
|
previous_run_times.dig(:meta, :average_run_time)
|
60
62
|
end
|
61
63
|
|
62
|
-
|
63
|
-
|
64
|
-
return unless path
|
65
|
-
return unless File.exist? path
|
64
|
+
def previous_run_times
|
65
|
+
return unless ENV["SPECWRK_OUT"]
|
66
66
|
|
67
|
-
|
68
|
-
|
67
|
+
@previous_run_times ||= begin
|
68
|
+
return unless previous_run_times_file_path
|
69
|
+
return unless File.exist? previous_run_times_file_path
|
69
70
|
|
70
|
-
|
71
|
+
raw_data = File.open(previous_run_times_file_path, "r") do |file|
|
72
|
+
file.flock(File::LOCK_SH)
|
73
|
+
file.read
|
74
|
+
end
|
71
75
|
|
72
|
-
|
76
|
+
@previous_run_times = JSON.parse(raw_data, symbolize_names: true)
|
77
|
+
rescue JSON::ParserError => e
|
78
|
+
warn "#{e.inspect} in file #{previous_run_times_file_path}"
|
79
|
+
nil
|
73
80
|
end
|
74
81
|
end
|
75
82
|
|
@@ -84,6 +91,15 @@ module Specwrk
|
|
84
91
|
|
85
92
|
private
|
86
93
|
|
94
|
+
# We want the most recently modified run time file
|
95
|
+
# report files are prefixed with a timestamp, and Dir.glob should order
|
96
|
+
# alphanumericly
|
97
|
+
def previous_run_times_file_path
|
98
|
+
return unless ENV["SPECWRK_OUT"]
|
99
|
+
|
100
|
+
@previous_run_times_file_path ||= Dir.glob(File.join(ENV["SPECWRK_OUT"], "*-report-*.json")).last
|
101
|
+
end
|
102
|
+
|
87
103
|
# Take elements from the hash where the file_path is the same
|
88
104
|
def bucket_by_file
|
89
105
|
bucket = []
|
@@ -163,7 +179,7 @@ module Specwrk
|
|
163
179
|
@hash.values.each { |example| calculate(example) }
|
164
180
|
|
165
181
|
@output[:meta][:total_run_time] = @run_times.sum
|
166
|
-
@output[:meta][:average_run_time] = @output[:meta][:total_run_time] / @run_times.length.to_f
|
182
|
+
@output[:meta][:average_run_time] = @output[:meta][:total_run_time] / [@run_times.length, 1].max.to_f
|
167
183
|
@output[:meta][:first_started_at] = @first_started_at.iso8601(6)
|
168
184
|
@output[:meta][:last_finished_at] = @last_finished_at.iso8601(6)
|
169
185
|
|
data/lib/specwrk/version.rb
CHANGED
data/lib/specwrk/web/app.rb
CHANGED
@@ -13,6 +13,7 @@ rescue LoadError
|
|
13
13
|
require "rack/handler/webrick"
|
14
14
|
end
|
15
15
|
|
16
|
+
require "specwrk/web"
|
16
17
|
require "specwrk/web/logger"
|
17
18
|
require "specwrk/web/auth"
|
18
19
|
require "specwrk/web/endpoints"
|
@@ -20,6 +21,8 @@ require "specwrk/web/endpoints"
|
|
20
21
|
module Specwrk
|
21
22
|
class Web
|
22
23
|
class App
|
24
|
+
REAP_INTERVAL = 330 # HTTP connection timeout + some buffer
|
25
|
+
|
23
26
|
class << self
|
24
27
|
def run!
|
25
28
|
Process.setproctitle "specwrk-server"
|
@@ -49,10 +52,8 @@ module Specwrk
|
|
49
52
|
|
50
53
|
def setup!
|
51
54
|
if ENV["SPECWRK_OUT"]
|
52
|
-
|
53
55
|
FileUtils.mkdir_p(ENV["SPECWRK_OUT"])
|
54
56
|
ENV["SPECWRK_SRV_LOG"] ||= Pathname.new(File.join(ENV["SPECWRK_OUT"], "server.log")).to_s unless ENV["SPECWRK_SRV_VERBOSE"]
|
55
|
-
ENV["SPECWRK_SRV_OUTPUT"] ||= Pathname.new(File.join(ENV["SPECWRK_OUT"], "report.json")).expand_path(Dir.pwd).to_s
|
56
57
|
end
|
57
58
|
|
58
59
|
if ENV["SPECWRK_SRV_LOG"]
|
@@ -73,6 +74,10 @@ module Specwrk
|
|
73
74
|
end
|
74
75
|
end
|
75
76
|
|
77
|
+
def initialize
|
78
|
+
@reaper_thread = Thread.new { reaper } unless ENV["SPECWRK_SRV_SINGLE_RUN"]
|
79
|
+
end
|
80
|
+
|
76
81
|
def call(env)
|
77
82
|
env[:request] ||= Rack::Request.new(env)
|
78
83
|
|
@@ -93,14 +98,34 @@ module Specwrk
|
|
93
98
|
Endpoints::Complete
|
94
99
|
when ["POST", "/seed"]
|
95
100
|
Endpoints::Seed
|
96
|
-
when ["GET", "/
|
97
|
-
Endpoints::
|
101
|
+
when ["GET", "/report"]
|
102
|
+
Endpoints::Report
|
98
103
|
when ["DELETE", "/shutdown"]
|
99
104
|
Endpoints::Shutdown
|
100
105
|
else
|
101
106
|
Endpoints::NotFound
|
102
107
|
end
|
103
108
|
end
|
109
|
+
|
110
|
+
def reaper
|
111
|
+
until Specwrk.force_quit
|
112
|
+
sleep REAP_INTERVAL
|
113
|
+
|
114
|
+
reap
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def reap
|
119
|
+
Web::WORKERS.each do |run, workers|
|
120
|
+
most_recent_last_seen_at = workers.map { |id, worker| worker[:last_seen_at] }.max
|
121
|
+
next unless most_recent_last_seen_at
|
122
|
+
|
123
|
+
# Don't consider runs which aren't at least REAP_INTERVAL sec stale
|
124
|
+
if most_recent_last_seen_at < Time.now - REAP_INTERVAL
|
125
|
+
Web.clear_run_queues(run)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
104
129
|
end
|
105
130
|
end
|
106
131
|
end
|
@@ -8,6 +8,9 @@ module Specwrk
|
|
8
8
|
class Base
|
9
9
|
def initialize(request)
|
10
10
|
@request = request
|
11
|
+
|
12
|
+
worker[:first_seen_at] ||= Time.now
|
13
|
+
worker[:last_seen_at] = Time.now
|
11
14
|
end
|
12
15
|
|
13
16
|
def response
|
@@ -35,7 +38,7 @@ module Specwrk
|
|
35
38
|
end
|
36
39
|
|
37
40
|
def pending_queue
|
38
|
-
Web::PENDING_QUEUES[
|
41
|
+
Web::PENDING_QUEUES[run_id]
|
39
42
|
end
|
40
43
|
|
41
44
|
def processing_queue
|
@@ -45,6 +48,22 @@ module Specwrk
|
|
45
48
|
def completed_queue
|
46
49
|
Web::COMPLETED_QUEUES[request.get_header("HTTP_X_SPECWRK_RUN")]
|
47
50
|
end
|
51
|
+
|
52
|
+
def workers
|
53
|
+
Web::WORKERS[request.get_header("HTTP_X_SPECWRK_RUN")]
|
54
|
+
end
|
55
|
+
|
56
|
+
def worker
|
57
|
+
workers[request.get_header("HTTP_X_SPECWRK_ID")]
|
58
|
+
end
|
59
|
+
|
60
|
+
def run_id
|
61
|
+
request.get_header("HTTP_X_SPECWRK_RUN")
|
62
|
+
end
|
63
|
+
|
64
|
+
def run_report_file_path
|
65
|
+
@run_report_file_path ||= File.join(ENV["SPECWRK_OUT"], "#{completed_queue.created_at.strftime("%Y%m%dT%H%M%S")}-report-#{run_id}.json").to_s
|
66
|
+
end
|
48
67
|
end
|
49
68
|
|
50
69
|
# Base default response is 404
|
@@ -87,8 +106,8 @@ module Specwrk
|
|
87
106
|
end
|
88
107
|
end
|
89
108
|
|
90
|
-
if pending_queue.length.zero? && processing_queue.length.zero? && completed_queue.length.positive? && ENV["
|
91
|
-
completed_queue.dump_and_write(
|
109
|
+
if pending_queue.length.zero? && processing_queue.length.zero? && completed_queue.length.positive? && ENV["SPECWRK_OUT"]
|
110
|
+
completed_queue.dump_and_write(run_report_file_path)
|
92
111
|
end
|
93
112
|
|
94
113
|
ok
|
@@ -117,43 +136,37 @@ module Specwrk
|
|
117
136
|
end
|
118
137
|
end
|
119
138
|
|
120
|
-
class
|
139
|
+
class Report < Base
|
121
140
|
def response
|
122
|
-
data
|
123
|
-
|
124
|
-
processing: {count: processing_queue.length},
|
125
|
-
completed: completed_queue.dump
|
126
|
-
}
|
127
|
-
|
128
|
-
if data.dig(:completed, :examples).length.positive?
|
129
|
-
[200, {"Content-Type" => "application/json"}, [JSON.generate(data)]]
|
141
|
+
if data
|
142
|
+
[200, {"Content-Type" => "application/json"}, [data]]
|
130
143
|
else
|
131
|
-
|
144
|
+
[404, {"Content-Type" => "text/plain"}, ["Unable to report on run #{run_id}; no file matching #{"*-report-#{run_id}.json"}"]]
|
132
145
|
end
|
133
146
|
end
|
134
|
-
end
|
135
147
|
|
136
|
-
|
137
|
-
def response
|
138
|
-
if ENV["SPECWRK_SRV_SINGLE_RUN"]
|
139
|
-
interupt!
|
140
|
-
elsif processing_queue.length.positive?
|
141
|
-
# Push any processing jobs back into the pending queue
|
142
|
-
processing_queue.synchronize do |processing_queue_hash|
|
143
|
-
pending_queue.synchronize do |pending_queue_hash|
|
144
|
-
processing_queue_hash.each do |id, example|
|
145
|
-
pending_queue_hash[id] = example
|
146
|
-
processing_queue_hash.delete(id)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
148
|
+
private
|
150
149
|
|
151
|
-
|
152
|
-
|
153
|
-
|
150
|
+
def data
|
151
|
+
return @data if defined? @data
|
152
|
+
|
153
|
+
return unless most_recent_run_report_file
|
154
|
+
return unless File.exist?(most_recent_run_report_file)
|
155
|
+
|
156
|
+
@data = File.open(most_recent_run_report_file, "r") do |file|
|
157
|
+
file.flock(File::LOCK_SH)
|
158
|
+
file.read
|
154
159
|
end
|
160
|
+
end
|
155
161
|
|
156
|
-
|
162
|
+
def most_recent_run_report_file
|
163
|
+
@most_recent_run_report_file ||= Dir.glob(File.join(ENV["SPECWRK_OUT"], "*-report-#{run_id}.json")).last
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
class Shutdown < Base
|
168
|
+
def response
|
169
|
+
interupt! if ENV["SPECWRK_SRV_SINGLE_RUN"]
|
157
170
|
|
158
171
|
[200, {"Content-Type" => "text/plain"}, ["✌️"]]
|
159
172
|
end
|
data/lib/specwrk/web.rb
CHANGED
@@ -4,12 +4,19 @@ require "specwrk/queue"
|
|
4
4
|
|
5
5
|
module Specwrk
|
6
6
|
class Web
|
7
|
-
PENDING_QUEUES = Queue.new { |h, key| h[key] = PendingQueue.new
|
7
|
+
PENDING_QUEUES = Queue.new { |h, key| h[key] = PendingQueue.new }
|
8
8
|
PROCESSING_QUEUES = Queue.new { |h, key| h[key] = Queue.new }
|
9
9
|
COMPLETED_QUEUES = Queue.new { |h, key| h[key] = CompletedQueue.new }
|
10
|
+
WORKERS = Hash.new { |h, key| h[key] = Hash.new { |h, key| h[key] = {} } }
|
10
11
|
|
11
12
|
def self.clear_queues
|
12
|
-
[PENDING_QUEUES, PROCESSING_QUEUES, COMPLETED_QUEUES].each(&:clear)
|
13
|
+
[PENDING_QUEUES, PROCESSING_QUEUES, COMPLETED_QUEUES, WORKERS].each(&:clear)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.clear_run_queues(run)
|
17
|
+
[PENDING_QUEUES, PROCESSING_QUEUES, COMPLETED_QUEUES, WORKERS].each do |queue|
|
18
|
+
queue.delete(run)
|
19
|
+
end
|
13
20
|
end
|
14
21
|
end
|
15
22
|
end
|