ci-queue 0.100.0 → 0.102.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/Gemfile.lock +1 -1
- data/lib/ci/queue/redis/requeue.lua +22 -7
- data/lib/ci/queue/redis/reserve.lua +18 -7
- data/lib/ci/queue/version.rb +1 -1
- data/lib/minitest/queue/runner.rb +16 -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: 24f5d0ca5b0d0391a953c6f0014635eec1b6ea541e7ac46a944ac413952777e0
|
|
4
|
+
data.tar.gz: aeec01bc647d5fb960449d57362cc6961479f5c6da78177c915c35bd9706f861
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 896cb4ac3e81d1235581e11ce6a0693565c6089afc441546a94d7211eab24b538279dfd6eb5abe06d7e3187e1b54bfb0f5d4127baa06d49a12baf181b345a444
|
|
7
|
+
data.tar.gz: 0be6036f02910f31672c28e2d6c6eb4cdbd41f066ffb499eed8e10990b2a7a8e6d596ecf9c3da5c57c574fc0a76ac73b430d447781c2929f615a2aa669ecbe74
|
data/Gemfile.lock
CHANGED
|
@@ -12,10 +12,30 @@ local leases_key = KEYS[9]
|
|
|
12
12
|
local max_requeues = tonumber(ARGV[1])
|
|
13
13
|
local global_max_requeues = tonumber(ARGV[2])
|
|
14
14
|
local entry = ARGV[3]
|
|
15
|
-
local offset = ARGV[4]
|
|
15
|
+
local offset = tonumber(ARGV[4]) or 0
|
|
16
16
|
local ttl = tonumber(ARGV[5])
|
|
17
17
|
local lease_id = ARGV[6]
|
|
18
18
|
|
|
19
|
+
-- Inserts `entry` behind the `offset` + 1 entries nearest the tail, the end RPOP reserves
|
|
20
|
+
-- from: where `LINSERT BEFORE <entry at index -(offset + 1)>` would put it. LINSERT finds its
|
|
21
|
+
-- pivot by scanning from the head, which is O(queue length) and blocks Redis on large queues;
|
|
22
|
+
-- this only touches the tail, so it is O(offset). Queues of at most `offset` + 1 entries, and
|
|
23
|
+
-- offsets of zero or less, push to the head instead.
|
|
24
|
+
-- Keep in sync with reserve.lua: the Python client does not resolve `-- @include`.
|
|
25
|
+
local function insert_with_offset(queue_key, entry, offset)
|
|
26
|
+
if offset <= 0 or redis.call('llen', queue_key) <= offset + 1 then
|
|
27
|
+
redis.call('lpush', queue_key, entry)
|
|
28
|
+
return
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
local ahead = redis.call('lrange', queue_key, -1 - offset, -1)
|
|
32
|
+
redis.call('ltrim', queue_key, 0, -2 - offset)
|
|
33
|
+
redis.call('rpush', queue_key, entry)
|
|
34
|
+
for _, ahead_entry in ipairs(ahead) do
|
|
35
|
+
redis.call('rpush', queue_key, ahead_entry)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
19
39
|
-- Only the current lease holder can requeue a test.
|
|
20
40
|
-- If the lease was transferred (e.g. via reserve_lost), reject the stale
|
|
21
41
|
-- worker's requeue so the running entry stays intact for the new holder.
|
|
@@ -42,12 +62,7 @@ redis.call('hincrby', requeues_count_key, entry, 1)
|
|
|
42
62
|
|
|
43
63
|
redis.call('hdel', error_reports_key, entry)
|
|
44
64
|
|
|
45
|
-
|
|
46
|
-
if pivot then
|
|
47
|
-
redis.call('linsert', queue_key, 'BEFORE', pivot, entry)
|
|
48
|
-
else
|
|
49
|
-
redis.call('lpush', queue_key, entry)
|
|
50
|
-
end
|
|
65
|
+
insert_with_offset(queue_key, entry, offset)
|
|
51
66
|
|
|
52
67
|
redis.call('hset', requeued_by_key, entry, worker_queue_key)
|
|
53
68
|
if ttl and ttl > 0 then
|
|
@@ -13,12 +13,23 @@ local current_time = ARGV[1]
|
|
|
13
13
|
local defer_offset = tonumber(ARGV[2]) or 0
|
|
14
14
|
local max_skip_attempts = 4
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
-- Inserts `entry` behind the `offset` + 1 entries nearest the tail, the end RPOP reserves
|
|
17
|
+
-- from: where `LINSERT BEFORE <entry at index -(offset + 1)>` would put it. LINSERT finds its
|
|
18
|
+
-- pivot by scanning from the head, which is O(queue length) and blocks Redis on large queues;
|
|
19
|
+
-- this only touches the tail, so it is O(offset). Queues of at most `offset` + 1 entries, and
|
|
20
|
+
-- offsets of zero or less, push to the head instead.
|
|
21
|
+
-- Keep in sync with requeue.lua: the Python client does not resolve `-- @include`.
|
|
22
|
+
local function insert_with_offset(queue_key, entry, offset)
|
|
23
|
+
if offset <= 0 or redis.call('llen', queue_key) <= offset + 1 then
|
|
24
|
+
redis.call('lpush', queue_key, entry)
|
|
25
|
+
return
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
local ahead = redis.call('lrange', queue_key, -1 - offset, -1)
|
|
29
|
+
redis.call('ltrim', queue_key, 0, -2 - offset)
|
|
30
|
+
redis.call('rpush', queue_key, entry)
|
|
31
|
+
for _, ahead_entry in ipairs(ahead) do
|
|
32
|
+
redis.call('rpush', queue_key, ahead_entry)
|
|
22
33
|
end
|
|
23
34
|
end
|
|
24
35
|
|
|
@@ -45,7 +56,7 @@ for attempt = 1, max_skip_attempts do
|
|
|
45
56
|
return claim_test(test)
|
|
46
57
|
end
|
|
47
58
|
|
|
48
|
-
insert_with_offset(test)
|
|
59
|
+
insert_with_offset(queue_key, test, defer_offset)
|
|
49
60
|
|
|
50
61
|
-- If this worker only finds its own requeued tests, defer once by returning nil,
|
|
51
62
|
-- then allow pickup on a subsequent reserve attempt.
|
data/lib/ci/queue/version.rb
CHANGED
|
@@ -304,7 +304,11 @@ module Minitest
|
|
|
304
304
|
step("Waiting for workers to complete")
|
|
305
305
|
|
|
306
306
|
unless supervisor.wait_for_workers { display_warnings(supervisor.build) }
|
|
307
|
-
|
|
307
|
+
# A lazy-load leader only marks the queue as initialized once it has
|
|
308
|
+
# streamed every test, but workers start on the first batch, so the wait
|
|
309
|
+
# can end (e.g. on --max-test-failed) while it is still streaming.
|
|
310
|
+
# Check streaming? first: the status only moves from streaming to ready.
|
|
311
|
+
unless supervisor.streaming? || supervisor.queue_initialized?
|
|
308
312
|
abort! "No leader was elected. This typically means no worker was able to start. Were there any errors during application boot?", 40
|
|
309
313
|
end
|
|
310
314
|
|
|
@@ -314,7 +318,7 @@ module Minitest
|
|
|
314
318
|
reporter.write_failure_file(queue_config.failure_file) if queue_config.failure_file
|
|
315
319
|
reporter.write_flaky_tests_file(queue_config.export_flaky_tests_file) if queue_config.export_flaky_tests_file
|
|
316
320
|
|
|
317
|
-
abort!(
|
|
321
|
+
abort!(unrun_tests_message(supervisor), exit_code)
|
|
318
322
|
end
|
|
319
323
|
end
|
|
320
324
|
|
|
@@ -447,6 +451,16 @@ module Minitest
|
|
|
447
451
|
Minitest::Queue::WorkerProfileReporter.new(supervisor).print_summary
|
|
448
452
|
end
|
|
449
453
|
|
|
454
|
+
def unrun_tests_message(supervisor)
|
|
455
|
+
# Read the status before the size: tests a streaming leader hasn't pushed
|
|
456
|
+
# yet aren't in the queue, so the size is only a lower bound.
|
|
457
|
+
if supervisor.streaming?
|
|
458
|
+
"At least #{supervisor.size} tests weren't run (the leader hadn't finished streaming tests to the queue)."
|
|
459
|
+
else
|
|
460
|
+
"#{supervisor.size} tests weren't run."
|
|
461
|
+
end
|
|
462
|
+
end
|
|
463
|
+
|
|
450
464
|
def parser
|
|
451
465
|
@parser ||= OptionParser.new do |opts|
|
|
452
466
|
opts.banner = "Usage: minitest-queue [options] COMMAND [ARGS]"
|