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.
122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/claude_agent_sdk/session_store.rb', line 122 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
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/claude_agent_sdk/session_store.rb', line 134 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
240 241 242 243 244 245 246 247 |
# File 'lib/claude_agent_sdk/session_store.rb', line 240 def clear @mutex.synchronize do @store.clear @mtimes.clear @summaries.clear @last_mtime = 0 end end |
#delete(key) ⇒ Object
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/claude_agent_sdk/session_store.rb', line 195 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).
226 227 228 |
# File 'lib/claude_agent_sdk/session_store.rb', line 226 def get_entries(key) @mutex.synchronize { (@store[key_to_string(key)] || []).dup } end |
#list_session_summaries(project_key) ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/claude_agent_sdk/session_store.rb', line 182 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
167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/claude_agent_sdk/session_store.rb', line 167 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
216 217 218 219 220 221 |
# File 'lib/claude_agent_sdk/session_store.rb', line 216 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
160 161 162 163 164 165 |
# File 'lib/claude_agent_sdk/session_store.rb', line 160 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).
231 232 233 234 235 236 237 238 |
# File 'lib/claude_agent_sdk/session_store.rb', line 231 def size @mutex.synchronize do @store.keys.count do |k| first_slash = k.index('/') first_slash && !k[(first_slash + 1)..].include?('/') end end end |