ci-queue 0.23.0 → 0.24.1

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: 652049f77362ba8fa3fd01b79a0260c5ff17ba678751ee2424de463afe035d38
4
- data.tar.gz: 745b2c493350d2315a10f36147d5d3b4cc74df74d5f38e82d2250f10be219d4a
3
+ metadata.gz: 2dddff029008b5dbe7ff19995f824f6c1d54a19e699377742a6e4599642f4b55
4
+ data.tar.gz: 9ff1268a7be473c4f35cb907193b24e04ae22189df0c116be9cc09db50112925
5
5
  SHA512:
6
- metadata.gz: d47070eca76cfd6191cc003191af153ba2b40596dca4c3408325389a110ae1b798e99dcdb7e27b33c23d5bf457d6eab003dd608602a5df9de38741408d7bb48a
7
- data.tar.gz: 0d2f4f69af4fc3714dbd6d5660d0e3106890a7bd5cef5782bae41847aa1552b35a8c9af6e77b7d8d18264b2100463062cb205f7ed45cef7646aeb2ff4ffe3bd3
6
+ metadata.gz: 755d03be6402d76d3d225c5c4dae6dafdf60f604fb6377c48403f98898b6ee6bc44634ad8d5dfdafe15f9ca2e3b8e304244850984f75aed67ae872064e9caedf
7
+ data.tar.gz: 157c12e846214542d78116fa168e380eba0b9266bcd2f3194d28c55951cc9c11cbc015582654ad6dfe09fac852e1123f3b9bbd8cd5b936ecdbf4075ce6a06784
data/dev.yml CHANGED
@@ -5,7 +5,7 @@ name: ci-queue
5
5
  up:
6
6
  - ruby: 2.6.5
7
7
  - bundler
8
- - railgun
8
+ - isogun
9
9
 
10
10
  commands:
11
11
  test: REDIS_HOST=ci-queue.railgun bundle exec rake test
@@ -3,11 +3,8 @@
3
3
  name: ci-queue
4
4
 
5
5
  vm:
6
- image: /opt/dev/misc/railgun-images/default
7
6
  ip_address: 192.168.64.245
8
7
  memory: 1G
9
8
  cores: 2
10
- volumes:
11
- root: 512M
12
9
  services:
13
10
  - redis
@@ -8,7 +8,7 @@ module CI
8
8
  attr_accessor :max_test_failed, :redis_ttl
9
9
  attr_reader :circuit_breakers
10
10
  attr_writer :seed, :build_id
11
- attr_writer :queue_init_timeout
11
+ attr_writer :queue_init_timeout, :report_timeout, :inactive_workers_timeout
12
12
 
13
13
  class << self
14
14
  def from_env(env)
@@ -35,7 +35,7 @@ module CI
35
35
  namespace: nil, seed: nil, flaky_tests: [], statsd_endpoint: nil, max_consecutive_failures: nil,
36
36
  grind_count: nil, max_duration: nil, failure_file: nil, max_test_duration: nil,
37
37
  max_test_duration_percentile: 0.5, track_test_duration: false, max_test_failed: nil,
38
- queue_init_timeout: nil, redis_ttl: 8 * 60 * 60
38
+ queue_init_timeout: nil, redis_ttl: 8 * 60 * 60, report_timeout: nil, inactive_workers_timeout: nil
39
39
  )
40
40
  @build_id = build_id
41
41
  @circuit_breakers = [CircuitBreaker::Disabled]
@@ -57,12 +57,22 @@ module CI
57
57
  self.max_consecutive_failures = max_consecutive_failures
58
58
  self.max_duration = max_duration
59
59
  @redis_ttl = redis_ttl
60
+ @report_timeout = report_timeout
61
+ @inactive_workers_timeout = inactive_workers_timeout
60
62
  end
61
63
 
62
64
  def queue_init_timeout
63
65
  @queue_init_timeout || timeout
64
66
  end
65
67
 
68
+ def report_timeout
69
+ @report_timeout || timeout
70
+ end
71
+
72
+ def inactive_workers_timeout
73
+ @inactive_workers_timeout || timeout
74
+ end
75
+
66
76
  def max_consecutive_failures=(max)
67
77
  if max
68
78
  @circuit_breakers << CircuitBreaker::MaxConsecutiveFailures.new(max_consecutive_failures: max)
@@ -5,6 +5,7 @@ module CI
5
5
  class Base
6
6
  include Common
7
7
 
8
+ TEN_MINUTES = 60 * 10
8
9
  CONNECTION_ERRORS = [
9
10
  ::Redis::BaseConnectionError,
10
11
  ::SocketError, # https://github.com/redis/redis-rb/pull/631
@@ -20,6 +21,19 @@ module CI
20
21
  queue_initialized? && size == 0
21
22
  end
22
23
 
24
+ def expired?
25
+ if (created_at = redis.get(key('created-at')))
26
+ (created_at.to_f + config.redis_ttl + TEN_MINUTES) < Time.now.to_f
27
+ else
28
+ # if there is no created at set anymore we assume queue is expired
29
+ true
30
+ end
31
+ end
32
+
33
+ def created_at=(timestamp)
34
+ redis.setnx(key('created-at'), timestamp)
35
+ end
36
+
23
37
  def size
24
38
  redis.multi do |transaction|
25
39
  transaction.llen(key('queue'))
@@ -61,6 +75,10 @@ module CI
61
75
  end
62
76
  end
63
77
 
78
+ def queue_initializing?
79
+ master_status == 'setup'
80
+ end
81
+
64
82
  def increment_test_failed
65
83
  redis.incr(key('test_failed_count'))
66
84
  end
@@ -21,17 +21,33 @@ module CI
21
21
 
22
22
  yield if block_given?
23
23
 
24
- time_left = config.timeout
25
- until exhausted? || time_left <= 0 || max_test_failed?
26
- sleep 1
24
+ time_left = config.report_timeout
25
+ time_left_with_no_workers = config.inactive_workers_timeout
26
+ until exhausted? || time_left <= 0 || max_test_failed? || time_left_with_no_workers <= 0
27
27
  time_left -= 1
28
+ sleep 1
29
+
30
+ if active_workers?
31
+ time_left_with_no_workers = config.inactive_workers_timeout
32
+ else
33
+ time_left_with_no_workers -= 1
34
+ end
28
35
 
29
36
  yield if block_given?
30
37
  end
38
+
39
+ puts "Aborting, it seems all workers died." if time_left_with_no_workers <= 0
31
40
  exhausted?
32
41
  rescue CI::Queue::Redis::LostMaster
33
42
  false
34
43
  end
44
+
45
+ private
46
+
47
+ def active_workers?
48
+ # if there are running jobs we assume there are still agents active
49
+ redis.zrangebyscore(key('running'), Time.now.to_f - config.timeout, "+inf", limit: [0,1]).count > 0
50
+ end
35
51
  end
36
52
  end
37
53
  end
@@ -11,6 +11,8 @@ module CI
11
11
  end
12
12
  end
13
13
 
14
+ TEN_MINUTES = 60 * 10
15
+
14
16
  attr_reader :progress, :total
15
17
 
16
18
  def initialize(tests, config)
@@ -37,6 +39,14 @@ module CI
37
39
  self
38
40
  end
39
41
 
42
+ def created_at=(timestamp)
43
+ @created_at ||= timestamp
44
+ end
45
+
46
+ def expired?
47
+ (@created_at.to_f TEN_MINUTES) < Time.now.to_f
48
+ end
49
+
40
50
  def populated?
41
51
  !!defined?(@index)
42
52
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module CI
4
4
  module Queue
5
- VERSION = '0.23.0'
5
+ VERSION = '0.24.1'
6
6
  DEV_SCRIPTS_ROOT = ::File.expand_path('../../../../../redis', __FILE__)
7
7
  RELEASE_SCRIPTS_ROOT = ::File.expand_path('../redis', __FILE__)
8
8
  end
@@ -47,7 +47,10 @@ module Minitest
47
47
  end
48
48
 
49
49
  def run_command
50
- if queue.retrying?
50
+ if queue.retrying? || retry?
51
+ if queue.expired?
52
+ abort! "The test run is too old and can't be retried"
53
+ end
51
54
  reset_counters
52
55
  retry_queue = queue.retry_queue
53
56
  if retry_queue.exhausted?
@@ -58,6 +61,8 @@ module Minitest
58
61
  end
59
62
  end
60
63
 
64
+ queue.rescue_connection_errors { queue.created_at = Time.now.to_f }
65
+
61
66
  set_load_path
62
67
  Minitest.queue = queue
63
68
  reporters = [
@@ -367,6 +372,24 @@ module Minitest
367
372
  queue_config.timeout = timeout
368
373
  end
369
374
 
375
+ help = <<~EOS
376
+ Specify a timeout after which the report command will fail if not all tests have been processed.
377
+ Defaults to the value set for --timeout.
378
+ EOS
379
+ opts.separator ""
380
+ opts.on('--report-timeout TIMEOUT', Float, help) do |timeout|
381
+ queue_config.report_timeout = timeout
382
+ end
383
+
384
+ help = <<~EOS
385
+ Specify a timeout after the report will fail if all workers are inactive (e.g. died).
386
+ Defaults to the value set for --timeout.
387
+ EOS
388
+ opts.separator ""
389
+ opts.on('--inactive-workers-timeout TIMEOUT', Float, help) do |timeout|
390
+ queue_config.inactive_workers_timeout = timeout
391
+ end
392
+
370
393
  help = <<~EOS
371
394
  Specify a timeout to elect the leader and populate the queue.
372
395
  Defaults to the value set for --timeout.
@@ -546,6 +569,11 @@ module Minitest
546
569
  puts red(message)
547
570
  exit! 1 # exit! is required to avoid minitest at_exit callback
548
571
  end
572
+
573
+ def retry?
574
+ ENV["BUILDKITE_RETRY_COUNT"].to_i > 0 ||
575
+ ENV["SEMAPHORE_PIPELINE_RERUN"] == "true"
576
+ end
549
577
  end
550
578
  end
551
579
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ci-queue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.0
4
+ version: 0.24.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-17 00:00:00.000000000 Z
11
+ date: 2022-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -171,6 +171,7 @@ files:
171
171
  - dev.yml
172
172
  - exe/minitest-queue
173
173
  - exe/rspec-queue
174
+ - isogun.yml
174
175
  - lib/ci/queue.rb
175
176
  - lib/ci/queue/bisect.rb
176
177
  - lib/ci/queue/build_record.rb
@@ -218,7 +219,6 @@ files:
218
219
  - lib/rspec/queue.rb
219
220
  - lib/rspec/queue/build_status_recorder.rb
220
221
  - lib/rspec/queue/order_recorder.rb
221
- - railgun.yml
222
222
  homepage: https://github.com/Shopify/ci-queue
223
223
  licenses:
224
224
  - MIT