Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/ci/unlock_pipeline_request.rb')
-rw-r--r--app/models/ci/unlock_pipeline_request.rb53
1 files changed, 53 insertions, 0 deletions
diff --git a/app/models/ci/unlock_pipeline_request.rb b/app/models/ci/unlock_pipeline_request.rb
new file mode 100644
index 00000000000..c8fc82f3e55
--- /dev/null
+++ b/app/models/ci/unlock_pipeline_request.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module Ci
+ class UnlockPipelineRequest
+ QUEUE_REDIS_KEY = 'ci_unlock_pipeline_requests:queue'
+
+ def self.enqueue(pipeline_id)
+ unix_timestamp = Time.current.utc.to_i
+ pipeline_ids = Array(pipeline_id).uniq
+ pipeline_ids_with_scores = pipeline_ids.map do |id|
+ # The order of values per pair is `[score, key]`, so in this case, the unix timestamp is the score.
+ # By default, the sort order of sorted sets is from lowest to highest, though this does not matter much
+ # because we use `ZPOPMIN` to make sure to return the lowest/oldest request in terms of unix timestamp score.
+ [unix_timestamp, id]
+ end
+
+ with_redis do |redis|
+ added = redis.zadd(QUEUE_REDIS_KEY, pipeline_ids_with_scores, nx: true)
+ log_event(:enqueued, pipeline_ids) if added > 0
+ added
+ end
+ end
+
+ def self.next!
+ with_redis do |redis|
+ pipeline_id, enqueue_timestamp = redis.zpopmin(QUEUE_REDIS_KEY)
+ break unless pipeline_id
+
+ pipeline_id = pipeline_id.to_i
+ log_event(:picked_next, pipeline_id)
+
+ [pipeline_id, enqueue_timestamp.to_i]
+ end
+ end
+
+ def self.total_pending
+ with_redis do |redis|
+ redis.zcard(QUEUE_REDIS_KEY)
+ end
+ end
+
+ def self.with_redis(&block)
+ Gitlab::Redis::SharedState.with(&block)
+ end
+
+ def self.log_event(event, pipeline_id)
+ Gitlab::AppLogger.info(
+ message: "Pipeline unlock - #{event}",
+ pipeline_id: pipeline_id
+ )
+ end
+ end
+end