Class: Woods::SessionTracer::FileStore

Inherits:
Store
  • Object
show all
Defined in:
lib/woods/session_tracer/file_store.rb

Overview

File-backed session store using JSONL (one JSON object per line).

Sessions are stored as individual files in a configurable directory:

{base_dir}/{session_id}.jsonl

Append-only with file locking for concurrency safety. Zero external dependencies.

Examples:

store = FileStore.new(base_dir: "tmp/woods/sessions")
store.record("abc123", { controller: "PostsController", action: "create" })
store.read("abc123") # => [{ "controller" => "PostsController", ... }]

Instance Method Summary collapse

Constructor Details

#initialize(base_dir:) ⇒ FileStore

Returns a new instance of FileStore.

Parameters:

  • base_dir (String)

    Directory for session JSONL files



23
24
25
26
27
# File 'lib/woods/session_tracer/file_store.rb', line 23

def initialize(base_dir:)
  super()
  @base_dir = base_dir
  FileUtils.mkdir_p(@base_dir)
end

Instance Method Details

#clear(session_id) ⇒ void

This method returns an undefined value.

Remove all data for a single session.

Parameters:

  • session_id (String)

    The session identifier



82
83
84
85
# File 'lib/woods/session_tracer/file_store.rb', line 82

def clear(session_id)
  path = session_path(session_id)
  FileUtils.rm_f(path)
end

#clear_allvoid

This method returns an undefined value.

Remove all session data.



90
91
92
93
# File 'lib/woods/session_tracer/file_store.rb', line 90

def clear_all
  pattern = File.join(@base_dir, '*.jsonl')
  Dir.glob(pattern).each { |f| File.delete(f) }
end

#read(session_id) ⇒ Array<Hash>

Read all request records for a session, ordered by file line order (timestamp).

Parameters:

  • session_id (String)

    The session identifier

Returns:

  • (Array<Hash>)

    Request records, oldest first



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/woods/session_tracer/file_store.rb', line 50

def read(session_id)
  path = session_path(session_id)
  return [] unless File.exist?(path)

  File.readlines(path).filter_map do |line|
    stripped = line.strip
    next if stripped.empty?

    JSON.parse(stripped)
  rescue JSON::ParserError
    nil
  end
end

#record(session_id, request_data) ⇒ void

This method returns an undefined value.

Append a request record to a session’s JSONL file.

Uses file locking (LOCK_EX) for concurrency safety.

Parameters:

  • session_id (String)

    The session identifier

  • request_data (Hash)

    Request metadata to store



36
37
38
39
40
41
42
43
44
# File 'lib/woods/session_tracer/file_store.rb', line 36

def record(session_id, request_data)
  path = session_path(session_id)
  line = "#{JSON.generate(request_data)}\n"

  File.open(path, 'a') do |f|
    f.flock(File::LOCK_EX)
    f.write(line)
  end
end

#sessions(limit: 20) ⇒ Array<Hash>

List recent session summaries, sorted by last modification time (newest first).

Parameters:

  • limit (Integer) (defaults to: 20)

    Maximum number of sessions to return

Returns:

  • (Array<Hash>)

    Session summaries



68
69
70
71
72
73
74
75
76
# File 'lib/woods/session_tracer/file_store.rb', line 68

def sessions(limit: 20)
  pattern = File.join(@base_dir, '*.jsonl')
  files = Dir.glob(pattern).sort_by { |f| -File.mtime(f).to_f }

  files.first(limit).map do |file|
    session_id = File.basename(file, '.jsonl')
    session_summary(session_id, read(session_id))
  end
end