Class: ClickHouse::MigrationSupport::ExclusiveLock

Inherits:
Object
  • Object
show all
Extended by:
Gitlab::ExclusiveLeaseHelpers
Defined in:
lib/click_house/migration_support/exclusive_lock.rb

Constant Summary collapse

MIGRATION_LEASE_KEY =
'click_house:migrations'
MIGRATION_RETRY_DELAY =
->(num) { 0.2.seconds * (num**2) }
MIGRATION_LOCK_DURATION =
1.hour
ACTIVE_WORKERS_REDIS_KEY =
'click_house:workers:active_workers'
DEFAULT_CLICKHOUSE_WORKER_TTL =
30.minutes
WORKERS_WAIT_SLEEP =
5.seconds

Constants included from Gitlab::ExclusiveLeaseHelpers

Gitlab::ExclusiveLeaseHelpers::FailedToObtainLockError

Class Method Summary collapse

Methods included from Gitlab::ExclusiveLeaseHelpers

in_lock

Class Method Details

.active_sidekiq_workers?Boolean

Returns:

  • (Boolean)


49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/click_house/migration_support/exclusive_lock.rb', line 49

def active_sidekiq_workers?
  Gitlab::Redis::SharedState.with do |redis|
    min = Time.now.utc.to_i

    # expire keys in the past
    redis.zremrangebyscore(ACTIVE_WORKERS_REDIS_KEY, 0, "(#{min}")
    # Return if any workers are registered with a future expiry date
    #
    # To be compatible with Redis 6.0 not use zrange with 'by_score: true' parameter
    # instead use redis.zrangebyscore method.
    redis.zrangebyscore(ACTIVE_WORKERS_REDIS_KEY, min, '+inf', limit: [0, 1]).any?
  end
end

.execute_migrationObject



35
36
37
38
39
40
41
42
43
# File 'lib/click_house/migration_support/exclusive_lock.rb', line 35

def execute_migration
  in_lock(MIGRATION_LEASE_KEY, ttl: MIGRATION_LOCK_DURATION, retries: 5, sleep_sec: MIGRATION_RETRY_DELAY) do
    wait_until_workers_inactive(DEFAULT_CLICKHOUSE_WORKER_TTL.from_now)

    yield
  end
rescue Gitlab::ExclusiveLeaseHelpers::FailedToObtainLockError => e
  raise ClickHouse::MigrationSupport::Errors::LockError, e.message
end

.pause_workers?Boolean

Returns:

  • (Boolean)


45
46
47
# File 'lib/click_house/migration_support/exclusive_lock.rb', line 45

def pause_workers?
  Gitlab::ExclusiveLease.new(MIGRATION_LEASE_KEY, timeout: 0).exists?
end

.register_running_worker(worker_class, worker_id) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/click_house/migration_support/exclusive_lock.rb', line 17

def register_running_worker(worker_class, worker_id)
  ttl = worker_class.click_house_worker_attrs[:migration_lock_ttl].from_now.utc

  Gitlab::Redis::SharedState.with do |redis|
    current_score = redis.zscore(ACTIVE_WORKERS_REDIS_KEY, worker_id).to_i

    if ttl.to_i > current_score
      # DO NOT send 'gt: true' parameter to avoid compatibility
      # problems with Redis versions older than 6.2.
      redis.zadd(ACTIVE_WORKERS_REDIS_KEY, ttl.to_i, worker_id)
    end

    yield
  ensure
    redis.zrem(ACTIVE_WORKERS_REDIS_KEY, worker_id)
  end
end