Class: Engram::Rails::CacheProcessedTurns

Inherits:
Object
  • Object
show all
Includes:
Ports::ProcessedTurns
Defined in:
lib/engram/rails/cache_processed_turns.rb

Overview

Claims use atomic unless-exist writes. Generic ActiveSupport caches do not expose compare-and-delete, so release leaves a claim in place until lease expiry and completion never deletes it.

Defined Under Namespace

Classes: CacheWriteError, NonAtomicCacheError

Instance Method Summary collapse

Constructor Details

#initialize(namespace: "engram:processed_turns", ttl: 86_400, lease_ttl: 300, cache: ::Rails.cache) ⇒ CacheProcessedTurns

Returns a new instance of CacheProcessedTurns.



17
18
19
20
21
22
# File 'lib/engram/rails/cache_processed_turns.rb', line 17

def initialize(namespace: "engram:processed_turns", ttl: 86_400, lease_ttl: 300, cache: ::Rails.cache)
  @namespace = namespace
  @ttl = ttl
  @lease_ttl = lease_ttl
  @cache = cache
end

Instance Method Details

#claim(scope:, key:) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/engram/rails/cache_processed_turns.rb', line 24

def claim(scope:, key:)
  return if completed?(scope: scope, key: key)
  token = SecureRandom.uuid
  result = @cache.write(claim_key(scope, key), token, expires_in: @lease_ttl, unless_exist: true)
  unless result == true || result == false
    raise NonAtomicCacheError, "cache backend must return true/false for atomic write(unless_exist: true)"
  end
  return unless result
  return token unless completed?(scope: scope, key: key)

  release(scope: scope, key: key, claim: token)
  nil
end

#complete(scope:, key:, claim:) ⇒ Object

Raises:



38
39
40
41
42
# File 'lib/engram/rails/cache_processed_turns.rb', line 38

def complete(scope:, key:, claim:)
  written = @cache.write(completed_key(scope, key), true, expires_in: @ttl)
  raise CacheWriteError, "cache backend failed to write completed observation" unless written
  true
end

#completed?(scope:, key:) ⇒ Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/engram/rails/cache_processed_turns.rb', line 49

def completed?(scope:, key:)
  @cache.exist?(completed_key(scope, key))
end

#release(scope:, key:, claim:) ⇒ Object



44
45
46
47
# File 'lib/engram/rails/cache_processed_turns.rb', line 44

def release(scope:, key:, claim:)
  # A read followed by delete could delete a successor lease.
  nil
end