Class: ClaudeAgentSDK::InMemorySessionStore
- Inherits:
-
SessionStore
- Object
- SessionStore
- ClaudeAgentSDK::InMemorySessionStore
- Defined in:
- lib/claude_agent_sdk/session_store.rb
Overview
In-memory SessionStore for testing and development. Data is lost when the process exits — not suitable for production.
Instance Method Summary collapse
- #append(key, entries) ⇒ Object
- #clear ⇒ Object
- #delete(key) ⇒ Object
-
#get_entries(key) ⇒ Object
All entries for a key (empty array if absent).
-
#initialize ⇒ InMemorySessionStore
constructor
A new instance of InMemorySessionStore.
- #list_session_summaries(project_key) ⇒ Object
- #list_sessions(project_key) ⇒ Object
- #list_subkeys(key) ⇒ Object
- #load(key) ⇒ Object
-
#size ⇒ Object
Number of stored sessions (main transcripts only).
Methods inherited from SessionStore
Constructor Details
#initialize ⇒ InMemorySessionStore
Returns a new instance of InMemorySessionStore.
96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/claude_agent_sdk/session_store.rb', line 96 def initialize super @store = {} @mtimes = {} @summaries = {} @last_mtime = 0 # The SessionStore#append contract requires per-key thread-safety, and two # concurrent sessions can share one store (each with its own batcher and # semaphore, so nothing serializes appends across them). Guard all access. @mutex = Mutex.new end |
Instance Method Details
#append(key, entries) ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/claude_agent_sdk/session_store.rb', line 108 def append(key, entries) # Same guard as the reference adapters: append(key, []) must not create a # phantom key (load would return [] instead of nil and the session would # appear in listings). return if entries.nil? || entries.empty? @mutex.synchronize do k = key_to_string(key) (@store[k] ||= []).concat(entries) now_ms = next_mtime # Maintain the per-session summary sidecar incrementally so # #list_session_summaries never re-reads. Subagent subpaths don't # contribute to the main session's summary. if main_transcript_key?(key) sk = [key['project_key'], key['session_id']] folded = SessionSummary.fold_session_summary(@summaries[sk], key, entries) # Stamp with this adapter's storage write time — the SAME clock # #list_sessions exposes, so the fast-path staleness check works. folded['mtime'] = now_ms @summaries[sk] = folded end @mtimes[k] = now_ms end nil end |
#clear ⇒ Object
214 215 216 217 218 219 220 221 |
# File 'lib/claude_agent_sdk/session_store.rb', line 214 def clear @mutex.synchronize do @store.clear @mtimes.clear @summaries.clear @last_mtime = 0 end end |
#delete(key) ⇒ Object
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/claude_agent_sdk/session_store.rb', line 169 def delete(key) @mutex.synchronize do k = key_to_string(key) @store.delete(k) @mtimes.delete(k) # Deleting the main transcript cascades to its subkeys so they aren't # orphaned. A targeted delete with an explicit subpath removes only that # one entry. An empty-string subpath is treated as "no subpath" (main), # consistent with key_to_string / append, so it cascades like nil. next unless main_transcript_key?(key) @summaries.delete([key['project_key'], key['session_id']]) prefix = "#{key['project_key']}/#{key['session_id']}/" @store.keys.select { |sk| sk.start_with?(prefix) }.each do |sk| @store.delete(sk) @mtimes.delete(sk) end end nil end |
#get_entries(key) ⇒ Object
All entries for a key (empty array if absent).
200 201 202 |
# File 'lib/claude_agent_sdk/session_store.rb', line 200 def get_entries(key) @mutex.synchronize { (@store[key_to_string(key)] || []).dup } end |
#list_session_summaries(project_key) ⇒ Object
156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/claude_agent_sdk/session_store.rb', line 156 def list_session_summaries(project_key) @mutex.synchronize do # Return COPIES, not the internal summary objects: #load dups, so this # must too, or a caller mutating a returned summary's data would corrupt # the sidecar that the next fold builds on. @summaries.filter_map do |(pk, _sid), summary| next unless pk == project_key { 'session_id' => summary['session_id'], 'mtime' => summary['mtime'], 'data' => summary['data'].dup } end end end |
#list_sessions(project_key) ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/claude_agent_sdk/session_store.rb', line 141 def list_sessions(project_key) prefix = "#{project_key}/" results = [] @mutex.synchronize do @store.each_key do |k| next unless k.start_with?(prefix) rest = k[prefix.length..] # Only main transcripts (no subpath, so no second '/'). results << { 'session_id' => rest, 'mtime' => @mtimes[k] || 0 } unless rest.include?('/') end end results end |
#list_subkeys(key) ⇒ Object
190 191 192 193 194 195 |
# File 'lib/claude_agent_sdk/session_store.rb', line 190 def list_subkeys(key) prefix = "#{key['project_key']}/#{key['session_id']}/" @mutex.synchronize do @store.keys.select { |k| k.start_with?(prefix) }.map { |k| k[prefix.length..] } end end |
#load(key) ⇒ Object
134 135 136 137 138 139 |
# File 'lib/claude_agent_sdk/session_store.rb', line 134 def load(key) @mutex.synchronize do entries = @store[key_to_string(key)] entries&.dup end end |
#size ⇒ Object
Number of stored sessions (main transcripts only).
205 206 207 208 209 210 211 212 |
# File 'lib/claude_agent_sdk/session_store.rb', line 205 def size @mutex.synchronize do @store.keys.count do |k| first_slash = k.index('/') first_slash && !k[(first_slash + 1)..].include?('/') end end end |