Class: Harnex::Adapters::CodexAppServer::JsonRpcClient

Inherits:
Object
  • Object
show all
Defined in:
lib/harnex/adapters/codex_appserver.rb

Overview

Minimal JSON-RPC 2.0 client. One JSON object per line. Responses keyed by id; everything else is a notification.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(read_io:, write_io:, pid: nil) ⇒ JsonRpcClient

Returns a new instance of JsonRpcClient.



297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
# File 'lib/harnex/adapters/codex_appserver.rb', line 297

def initialize(read_io:, write_io:, pid: nil)
  @read_io = read_io
  @write_io = write_io
  @pid = pid
  @next_id = 1
  @pending = {}
  @id_mutex = Mutex.new
  @write_mutex = Mutex.new
  @notification_handler = nil
  @request_handler = nil
  @disconnect_handler = nil
  @disconnect_signaled = false
  @closed = false
  @reader_thread = nil
end

Instance Attribute Details

#pidObject (readonly)

Returns the value of attribute pid.



295
296
297
# File 'lib/harnex/adapters/codex_appserver.rb', line 295

def pid
  @pid
end

Instance Method Details

#closeObject



356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
# File 'lib/harnex/adapters/codex_appserver.rb', line 356

def close
  return if @closed

  @closed = true

  @id_mutex.synchronize do
    @pending.each_value { |q| q.push(StandardError.new("codex_appserver client closed")) }
    @pending.clear
  end

  begin
    @write_io.close unless @write_io.closed?
  rescue IOError
    nil
  end

  if @pid && process_alive?(@pid)
    sleep 0.05
    begin
      Process.kill("TERM", @pid)
    rescue Errno::ESRCH
      nil
    end
  end

  @reader_thread&.join(2)
end

#notify(method, params = {}) ⇒ Object



350
351
352
353
354
# File 'lib/harnex/adapters/codex_appserver.rb', line 350

def notify(method, params = {})
  return if @closed

  write_line({ jsonrpc: "2.0", method: method, params: params })
end

#on_disconnect(&block) ⇒ Object



324
325
326
# File 'lib/harnex/adapters/codex_appserver.rb', line 324

def on_disconnect(&block)
  @disconnect_handler = block
end

#on_notification(&block) ⇒ Object



313
314
315
# File 'lib/harnex/adapters/codex_appserver.rb', line 313

def on_notification(&block)
  @notification_handler = block
end

#on_request(&block) ⇒ Object

Handler for server-initiated requests (id + method). The block receives (method, params) and returns the response body for the JSON-RPC ‘result` field, or nil to reject with -32601.



320
321
322
# File 'lib/harnex/adapters/codex_appserver.rb', line 320

def on_request(&block)
  @request_handler = block
end

#request(method, params = {}) ⇒ Object



332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# File 'lib/harnex/adapters/codex_appserver.rb', line 332

def request(method, params = {})
  raise "codex_appserver client is closed" if @closed

  queue = Queue.new
  id = @id_mutex.synchronize do
    assigned = @next_id
    @next_id += 1
    @pending[assigned] = queue
    assigned
  end

  write_line({ jsonrpc: "2.0", id: id, method: method, params: params })
  result = queue.pop
  raise result if result.is_a?(Exception)

  result
end

#startObject



328
329
330
# File 'lib/harnex/adapters/codex_appserver.rb', line 328

def start
  @reader_thread = Thread.new { read_loop }
end