Class: OllamaAgent::Runtime::LockManager

Inherits:
Object
  • Object
show all
Defined in:
lib/ollama_agent/runtime/lock_manager.rb

Overview

Exclusive leases in runtime.db keyed by scope (caller-chosen string, often a path).

Callers that acquire multiple scopes must do so in a consistent **lexicographic sort order** across the codebase to avoid deadlocks; this class does not reorder scopes for you. rubocop:disable Metrics/ClassLength – kernel lease + fencing in one cohesive unit

Constant Summary collapse

UPSERT_LOCK_SQL =
"INSERT INTO locks " \
"(scope, lease_token, holder, acquired_at, expires_at_epoch, fencing_token) " \
"VALUES (?,?,?,?,?,?) " \
"ON CONFLICT(scope) DO UPDATE SET " \
"lease_token = excluded.lease_token, holder = excluded.holder, " \
"acquired_at = excluded.acquired_at, expires_at_epoch = excluded.expires_at_epoch, " \
"fencing_token = excluded.fencing_token"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(db:, fencing_allocator:, clock_epoch:) ⇒ LockManager

Returns a new instance of LockManager.

Parameters:

  • db (SQLite3::Database)
  • fencing_allocator (FencingAllocator)
  • clock_epoch (Integer)

    initial logical epoch watermark (callers still pass current_epoch: per call)



26
27
28
29
30
# File 'lib/ollama_agent/runtime/lock_manager.rb', line 26

def initialize(db:, fencing_allocator:, clock_epoch:)
  @db = db
  @fencing_allocator = fencing_allocator
  @clock_epoch = clock_epoch
end

Instance Attribute Details

#clock_epochObject (readonly)

Returns the value of attribute clock_epoch.



21
22
23
# File 'lib/ollama_agent/runtime/lock_manager.rb', line 21

def clock_epoch
  @clock_epoch
end

Instance Method Details

#acquire(scope:, holder:, ttl_epochs:, current_epoch:) ⇒ Hash{:lease_token=>Integer, :fencing_token=>Integer}, ...

Returns:

  • (Hash{:lease_token=>Integer, :fencing_token=>Integer}, :held, :stale_lease)


33
34
35
36
37
38
39
40
41
# File 'lib/ollama_agent/runtime/lock_manager.rb', line 33

def acquire(scope:, holder:, ttl_epochs:, current_epoch:)
  return :stale_lease if ttl_epochs.to_i < 1

  outcome = nil
  @db.transaction(:immediate) do
    outcome = resolve_acquire(scope, holder, ttl_epochs, current_epoch)
  end
  outcome
end

#prune_expired(current_epoch:) ⇒ Integer

Returns rows deleted.

Returns:

  • (Integer)

    rows deleted



64
65
66
67
68
69
# File 'lib/ollama_agent/runtime/lock_manager.rb', line 64

def prune_expired(current_epoch:)
  @db.transaction(:immediate) do
    @db.execute("DELETE FROM locks WHERE expires_at_epoch <= ?", [current_epoch.to_i])
    @db.changes
  end
end

#release(scope:, holder:, lease_token:) ⇒ :ok, :stale_lease

Returns:

  • (:ok, :stale_lease)


55
56
57
58
59
60
61
# File 'lib/ollama_agent/runtime/lock_manager.rb', line 55

def release(scope:, holder:, lease_token:)
  outcome = :ok
  @db.transaction(:immediate) do
    outcome = resolve_release(scope, holder, lease_token)
  end
  outcome
end

#renew(scope:, holder:, lease_token:, ttl_epochs:, current_epoch:) ⇒ :ok, ...

Returns:

  • (:ok, :stale_lease, :expired)


44
45
46
47
48
49
50
51
52
# File 'lib/ollama_agent/runtime/lock_manager.rb', line 44

def renew(scope:, holder:, lease_token:, ttl_epochs:, current_epoch:)
  return :stale_lease if ttl_epochs.to_i < 1

  outcome = :ok
  @db.transaction(:immediate) do
    outcome = resolve_renew(scope, holder, lease_token, ttl_epochs, current_epoch)
  end
  outcome
end