Class: Ask::Rails::State

Inherits:
State::Adapter
  • Object
show all
Defined in:
lib/ask/rails/state.rb

Overview

ActiveRecord-backed state adapter for the ask_state table.

Used by ask-graph (workflow checkpoints) and any other ask component that needs durable key-value storage in the Rails database. Works with any Rails database adapter — PostgreSQL, MySQL, SQLite — because the value column is a portable JSON type.

Examples:

store = Ask::Rails::State.new
store.set("checkpoint:1", { completed: true })
store.get("checkpoint:1")  # => { "completed" => true }

Defined Under Namespace

Classes: Record

Instance Method Summary collapse

Instance Method Details

#clearObject



43
44
45
# File 'lib/ask/rails/state.rb', line 43

def clear
  Record.delete_all
end

#delete(key) ⇒ Object



39
40
41
# File 'lib/ask/rails/state.rb', line 39

def delete(key)
  Record.where(key: key).delete_all
end

#get(key) ⇒ Object



23
24
25
26
27
28
29
# File 'lib/ask/rails/state.rb', line 23

def get(key)
  record = Record.find_by(key: key)
  return nil unless record
  return nil if record.expires_at && record.expires_at <= Time.current

  record.value
end

#keys(pattern: nil) ⇒ Object



47
48
49
50
51
52
53
54
# File 'lib/ask/rails/state.rb', line 47

def keys(pattern: nil)
  scope = Record.all
  if pattern
    like = self.class.glob_to_like(pattern)
    scope = scope.where("key LIKE ?", like)
  end
  scope.pluck(:key)
end

#list_append(key, value, max_length: nil) ⇒ Object

Ordered lists — stored as an array in the value column. Required by Ask::Agent::Persistence::Base for session indexes.



66
67
68
69
70
71
# File 'lib/ask/rails/state.rb', line 66

def list_append(key, value, max_length: nil)
  entries = list_range(key)
  entries << value
  entries = entries.last(max_length) if max_length
  set(key, entries)
end

#list_range(key, start = 0, stop = -1)) ⇒ Object



73
74
75
76
77
78
# File 'lib/ask/rails/state.rb', line 73

def list_range(key, start = 0, stop = -1)
  entries = get(key)
  return [] unless entries.is_a?(Array)

  entries[start..stop] || []
end

#list_remove(key, value) ⇒ Object



80
81
82
83
84
85
86
87
88
# File 'lib/ask/rails/state.rb', line 80

def list_remove(key, value)
  entries = get(key)
  return 0 unless entries.is_a?(Array)

  before = entries.size
  entries.delete(value)
  set(key, entries)
  before - entries.size
end

#set(key, value, ttl: nil) ⇒ Object



31
32
33
34
35
36
37
# File 'lib/ask/rails/state.rb', line 31

def set(key, value, ttl: nil)
  record = Record.find_or_initialize_by(key: key)
  record.value = value
  record.expires_at = ttl ? Time.current + ttl : nil
  record.save!
  value
end

#set_if_not_exists(key, value, ttl: nil) ⇒ Object



56
57
58
59
60
61
# File 'lib/ask/rails/state.rb', line 56

def set_if_not_exists(key, value, ttl: nil)
  return false if exists?(key)

  set(key, value, ttl: ttl)
  true
end