Class: Phronomy::StateStore::File

Inherits:
Base
  • Object
show all
Defined in:
lib/phronomy/state_store/file.rb

Overview

Note:

This store is suitable for single-process use (development, CLI tools, tests). It is not safe for concurrent access across multiple processes without external locking.

File-system-backed state store. Persists graph state as a JSON file under a configurable directory. No additional server or database migration is required — it works with the local file system out of the box.

Each thread_id is stored as a separate file named ".json". The thread_id is sanitised before use as a filename to prevent path traversal: only alphanumeric characters, hyphens, underscores, and dots are allowed; all other characters are replaced with underscores.

Examples:

store = Phronomy::StateStore::File.new(dir: "tmp/workflow_states")
Phronomy::Workflow.define(MyContext, state_store: store) do
  # ...
end

Instance Method Summary collapse

Constructor Details

#initialize(dir: ::File.join(::Dir.tmpdir, "phronomy_states")) ⇒ File

Returns a new instance of File.

Parameters:

  • dir (String) (defaults to: ::File.join(::Dir.tmpdir, "phronomy_states"))

    directory where state files are stored. Created automatically if it does not exist.



30
31
32
33
# File 'lib/phronomy/state_store/file.rb', line 30

def initialize(dir: ::File.join(::Dir.tmpdir, "phronomy_states"))
  @dir = ::File.expand_path(dir)
  ::FileUtils.mkdir_p(@dir)
end

Instance Method Details

#clear(thread_id) ⇒ self

Removes the saved state file for the given thread_id.

Parameters:

  • thread_id (String)

Returns:

  • (self)


54
55
56
57
58
# File 'lib/phronomy/state_store/file.rb', line 54

def clear(thread_id)
  file = path(thread_id)
  ::File.delete(file) if ::File.exist?(file)
  self
end

#clear_allself

Removes all state files managed by this store instance.

Returns:

  • (self)


62
63
64
65
# File 'lib/phronomy/state_store/file.rb', line 62

def clear_all
  ::Dir.glob(::File.join(@dir, "*.json")).each { |f| ::File.delete(f) }
  self
end

#directoryString

Returns the directory used by this store.

Returns:

  • (String)

    the directory used by this store



68
69
70
# File 'lib/phronomy/state_store/file.rb', line 68

def directory
  @dir
end

#load(thread_id) ⇒ Object?

Returns state instance or nil if not found.

Parameters:

  • thread_id (String)

Returns:

  • (Object, nil)

    state instance or nil if not found



44
45
46
47
48
49
# File 'lib/phronomy/state_store/file.rb', line 44

def load(thread_id)
  file = path(thread_id)
  return nil unless ::File.exist?(file)

  deserialize_state(::File.read(file))
end

#save(state) ⇒ self

Parameters:

  • state (Object)

    includes Phronomy::WorkflowContext; must have a non-nil thread_id

Returns:

  • (self)


37
38
39
40
# File 'lib/phronomy/state_store/file.rb', line 37

def save(state)
  ::File.write(path(state.thread_id), serialize_state(state))
  self
end