Class: Schked::RedisJobRunStore

Inherits:
Object
  • Object
show all
Includes:
JobRunStore
Defined in:
lib/schked/redis_job_run_store.rb

Overview

Redis-backed implementation of the per-job coordination store. Uses SET key 1 NX EX <ttl> so the first caller wins and TTL handles expiration; #cleanup is a no-op because native TTL covers retention.

Constant Summary collapse

KEY_PREFIX =
"schked:job_run"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(redis_client:, logger: Logger.new($stdout), max_skew_seconds: 60) ⇒ RedisJobRunStore

Returns a new instance of RedisJobRunStore.



14
15
16
17
18
# File 'lib/schked/redis_job_run_store.rb', line 14

def initialize(redis_client:, logger: Logger.new($stdout), max_skew_seconds: 60)
  @redis_client = redis_client
  @logger = logger
  @max_skew_seconds = Integer(max_skew_seconds)
end

Instance Attribute Details

#loggerObject (readonly)

Returns the value of attribute logger.



12
13
14
# File 'lib/schked/redis_job_run_store.rb', line 12

def logger
  @logger
end

#max_skew_secondsObject (readonly)

Returns the value of attribute max_skew_seconds.



12
13
14
# File 'lib/schked/redis_job_run_store.rb', line 12

def max_skew_seconds
  @max_skew_seconds
end

#redis_clientObject (readonly)

Returns the value of attribute redis_client.



12
13
14
# File 'lib/schked/redis_job_run_store.rb', line 12

def redis_client
  @redis_client
end

Instance Method Details

#claim(job_name, window_start) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/schked/redis_job_run_store.rb', line 20

def claim(job_name, window_start)
  validate!(job_name, window_start)

  key = build_key(job_name, window_start)
  ttl = default_ttl

  # +SET ... NX EX+ is atomic on a single Redis instance and is the
  # idiomatic primitive for "claim this slot for at most N seconds".
  # Transport errors (connection refused, timeout, ...) raise out of
  # this method so the caller knows the store is unavailable — silently
  # returning +false+ would skip every job while Redis is down.
  #
  # Why not Redlock? Redlock (the algorithm used by +RedisLocker+) is
  # designed for cluster-wide consensus across multiple Redis masters.
  # For this dedup, a single +SET NX EX+ is already atomic per
  # instance and sufficient for exactly-once across the cluster of
  # *schedulers* — the scheduler cluster itself uses one Redis (or a
  # single master with replicas).
  redis_client.call("SET", key, "1", "NX", "EX", ttl) == "OK"
end

#cleanup(_older_than) ⇒ Object



41
42
43
44
# File 'lib/schked/redis_job_run_store.rb', line 41

def cleanup(_older_than)
  # Native Redis TTL handles expiration; nothing to do here.
  nil
end