Class: A2A::Server::Storage::Memory

Inherits:
Base
  • Object
show all
Defined in:
lib/a2a/server/storage/memory.rb

Instance Method Summary collapse

Methods inherited from Base

#task_exists?

Constructor Details

#initializeMemory

Initialize the memory storage with performance optimizations



16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/a2a/server/storage/memory.rb', line 16

def initialize
  @tasks = {}
  @push_configs = {}
  @context_index = {} # Index for faster context-based lookups
  @mutex = Mutex.new
  @stats = {
    reads: 0,
    writes: 0,
    cache_hits: 0,
    cache_misses: 0
  }
end

Instance Method Details

#apply_basic_filters(tasks, filters) ⇒ Object (private)



237
238
239
240
241
# File 'lib/a2a/server/storage/memory.rb', line 237

def apply_basic_filters(tasks, filters)
  tasks = tasks.select { |task| task.status&.state == filters[:state] } if filters[:state]
  tasks = tasks.select { |task| task.context_id == filters[:context_id] } if filters[:context_id]
  tasks
end

#apply_metadata_filters(tasks, filters) ⇒ Object (private)



243
244
245
246
247
248
249
250
# File 'lib/a2a/server/storage/memory.rb', line 243

def (tasks, filters)
  filters.each do |key, value|
    next if i[state context_id].include?(key)

    tasks = tasks.select { |task| apply_single_filter(task, key, value) }
  end
  tasks
end

#apply_single_filter(task, key, value) ⇒ Object (private)



252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/a2a/server/storage/memory.rb', line 252

def apply_single_filter(task, key, value)
  case key
  when :task_type
    task.&.dig(:type) == value || task.&.dig("type") == value
  when :created_after
    created_at = get_created_at(task)
    created_at && Time.parse(created_at) > value
  when :created_before
    created_at = get_created_at(task)
    created_at && Time.parse(created_at) < value
  else
    # Generic metadata filter
    task.&.dig(key) == value || task.&.dig(key.to_s) == value
  end
end

#cache_hit_ratioFloat

Get cache hit ratio

Returns:

  • (Float)

    Cache hit ratio (0.0 to 1.0)



226
227
228
229
230
231
232
233
# File 'lib/a2a/server/storage/memory.rb', line 226

def cache_hit_ratio
  @mutex.synchronize do
    total_reads = @stats[:cache_hits] + @stats[:cache_misses]
    return 0.0 if total_reads.zero?

    @stats[:cache_hits].to_f / total_reads
  end
end

#clear_all_tasksvoid

This method returns an undefined value.

Clear all tasks



129
130
131
132
133
# File 'lib/a2a/server/storage/memory.rb', line 129

def clear_all_tasks
  @mutex.synchronize do
    @tasks.clear
  end
end

#delete_push_notification_config(task_id, config_id) ⇒ Boolean

Delete a push notification config

Parameters:

  • task_id (String)

    The task ID

  • config_id (String)

    The config ID

Returns:

  • (Boolean)

    True if deleted, false if not found



186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/a2a/server/storage/memory.rb', line 186

def delete_push_notification_config(task_id, config_id)
  @mutex.synchronize do
    task_configs = @push_configs[task_id]
    return false unless task_configs

    deleted = !task_configs.delete(config_id).nil?

    # Clean up empty task entries
    @push_configs.delete(task_id) if task_configs.empty?

    deleted
  end
end

#delete_task(task_id) ⇒ Boolean

Delete a task by ID

Parameters:

  • task_id (String)

    The task ID

Returns:

  • (Boolean)

    True if task was deleted, false if not found



69
70
71
72
73
# File 'lib/a2a/server/storage/memory.rb', line 69

def delete_task(task_id)
  @mutex.synchronize do
    !@tasks.delete(task_id).nil?
  end
end

#get_created_at(task) ⇒ Object (private)



268
269
270
# File 'lib/a2a/server/storage/memory.rb', line 268

def get_created_at(task)
  task.&.dig(:created_at) || task.&.dig("created_at")
end

#get_push_notification_config_by_id(task_id, config_id) ⇒ A2A::Types::TaskPushNotificationConfig?

Get a push notification config by task and config ID

Parameters:

  • task_id (String)

    The task ID

  • config_id (String)

    The config ID

Returns:



163
164
165
166
167
# File 'lib/a2a/server/storage/memory.rb', line 163

def get_push_notification_config_by_id(task_id, config_id)
  @mutex.synchronize do
    @push_configs.dig(task_id, config_id)
  end
end

#get_task(task_id) ⇒ A2A::Types::Task?

Get a task by ID with performance tracking

Parameters:

  • task_id (String)

    The task ID

Returns:



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/a2a/server/storage/memory.rb', line 51

def get_task(task_id)
  @mutex.synchronize do
    @stats[:reads] += 1
    task = @tasks[task_id]
    if task
      @stats[:cache_hits] += 1
    else
      @stats[:cache_misses] += 1
    end
    task
  end
end

#list_all_tasksArray<A2A::Types::Task>

List all tasks

Returns:



102
103
104
105
106
# File 'lib/a2a/server/storage/memory.rb', line 102

def list_all_tasks
  @mutex.synchronize do
    @tasks.values.dup
  end
end

#list_push_notification_configs(task_id) ⇒ Array<A2A::Types::TaskPushNotificationConfig>

List all push notification configs for a task

Parameters:

  • task_id (String)

    The task ID

Returns:



174
175
176
177
178
# File 'lib/a2a/server/storage/memory.rb', line 174

def list_push_notification_configs(task_id)
  @mutex.synchronize do
    (@push_configs[task_id] || {}).values
  end
end

#list_tasks(**filters) ⇒ Array<A2A::Types::Task>

List tasks with optional filtering

Parameters:

  • filters (Hash)

    Optional filters (state, context_id, etc.)

Returns:



113
114
115
116
117
118
119
120
121
122
123
# File 'lib/a2a/server/storage/memory.rb', line 113

def list_tasks(**filters)
  @mutex.synchronize do
    @stats[:reads] += 1
    tasks = @tasks.values

    tasks = apply_basic_filters(tasks, filters)
    tasks = (tasks, filters)

    tasks.dup
  end
end

#list_tasks_by_context(context_id) ⇒ Array<A2A::Types::Task>

List all tasks for a given context ID using optimized index

Parameters:

  • context_id (String)

    The context ID

Returns:



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/a2a/server/storage/memory.rb', line 80

def list_tasks_by_context(context_id)
  @mutex.synchronize do
    @stats[:reads] += 1

    # Use context index for faster lookups
    task_ids = @context_index[context_id] || []
    tasks = task_ids.filter_map { |id| @tasks[id] }

    if tasks.any?
      @stats[:cache_hits] += 1
    else
      @stats[:cache_misses] += 1
    end

    tasks
  end
end

#performance_statsHash

Get storage performance statistics

Returns:

  • (Hash)

    Performance statistics



204
205
206
# File 'lib/a2a/server/storage/memory.rb', line 204

def performance_stats
  @mutex.synchronize { @stats.dup }
end

#reset_performance_stats!Object

Reset performance statistics



211
212
213
214
215
216
217
218
219
220
# File 'lib/a2a/server/storage/memory.rb', line 211

def reset_performance_stats!
  @mutex.synchronize do
    @stats = {
      reads: 0,
      writes: 0,
      cache_hits: 0,
      cache_misses: 0
    }
  end
end

#save_push_notification_config(config) ⇒ void

This method returns an undefined value.

Save a push notification config

Parameters:



150
151
152
153
154
155
# File 'lib/a2a/server/storage/memory.rb', line 150

def save_push_notification_config(config)
  @mutex.synchronize do
    @push_configs[config.task_id] ||= {}
    @push_configs[config.task_id][config.push_notification_config.id] = config
  end
end

#save_task(task) ⇒ void

This method returns an undefined value.

Save a task to memory with context indexing

Parameters:



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/a2a/server/storage/memory.rb', line 34

def save_task(task)
  @mutex.synchronize do
    @tasks[task.id] = task

    # Update context index for faster lookups
    @context_index[task.context_id] ||= []
    @context_index[task.context_id] << task.id unless @context_index[task.context_id].include?(task.id)

    @stats[:writes] += 1
  end
end

#task_countInteger

Get the number of stored tasks

Returns:

  • (Integer)

    Number of tasks



139
140
141
142
143
# File 'lib/a2a/server/storage/memory.rb', line 139

def task_count
  @mutex.synchronize do
    @tasks.size
  end
end