Class: Muxi::Transport

Inherits:
Object
  • Object
show all
Defined in:
lib/muxi/transport.rb

Constant Summary collapse

RETRY_STATUSES =
[429, 500, 502, 503, 504].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_url:, key_id:, secret_key:, timeout: 30, max_retries: 0, debug: false, logger: nil, app: nil) ⇒ Transport

Returns a new instance of Transport.



15
16
17
18
19
20
21
22
23
24
# File 'lib/muxi/transport.rb', line 15

def initialize(base_url:, key_id:, secret_key:, timeout: 30, max_retries: 0, debug: false, logger: nil, app: nil)
  @base_url = base_url.chomp("/")
  @key_id = (key_id || "").strip
  @secret_key = (secret_key || "").strip
  @timeout = timeout || 30
  @max_retries = max_retries || 0
  @debug = debug || Muxi.debug?
  @logger = logger || Logger.new($stdout, level: Logger::DEBUG)
  @app = app
end

Instance Attribute Details

#base_urlObject (readonly)

Returns the value of attribute base_url.



11
12
13
# File 'lib/muxi/transport.rb', line 11

def base_url
  @base_url
end

#debugObject (readonly)

Returns the value of attribute debug.



11
12
13
# File 'lib/muxi/transport.rb', line 11

def debug
  @debug
end

#key_idObject (readonly)

Returns the value of attribute key_id.



11
12
13
# File 'lib/muxi/transport.rb', line 11

def key_id
  @key_id
end

#loggerObject (readonly)

Returns the value of attribute logger.



11
12
13
# File 'lib/muxi/transport.rb', line 11

def logger
  @logger
end

#max_retriesObject (readonly)

Returns the value of attribute max_retries.



11
12
13
# File 'lib/muxi/transport.rb', line 11

def max_retries
  @max_retries
end

#secret_keyObject (readonly)

Returns the value of attribute secret_key.



11
12
13
# File 'lib/muxi/transport.rb', line 11

def secret_key
  @secret_key
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



11
12
13
# File 'lib/muxi/transport.rb', line 11

def timeout
  @timeout
end

Instance Method Details

#request_json(method, path, params: nil, body: nil) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/muxi/transport.rb', line 26

def request_json(method, path, params: nil, body: nil)
  url, full_path = build_url(path, params)
  headers = build_headers(method, full_path)

  attempt = 0
  backoff = 0.5

  loop do
    start_time = Time.now
    begin
      response = execute_request(method, url, headers, body)
      elapsed = Time.now - start_time
      log("#{method} #{full_path} -> #{response.code} (#{elapsed.round(3)}s)")

      # Check for SDK updates (non-blocking, once per process)
      VersionCheck.check_for_updates(response.to_hash.transform_values(&:first))

      if response.code.to_i >= 400
        handle_error_response(response, method, url, attempt, backoff)
        backoff *= 2
        attempt += 1
        next if attempt <= @max_retries
      end

      return parse_response(response)
    rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT, Net::OpenTimeout, SocketError => e
      if attempt < @max_retries
        sleep_for = [backoff, 30].min
        log("retry #{method} #{full_path} after #{sleep_for}s due to connection error: #{e}")
        sleep(sleep_for)
        backoff *= 2
        attempt += 1
        next
      end
      raise ConnectionError.new("CONNECTION_ERROR", e.message, 0)
    end
  end
end

#stream_lines(method, path, params: nil, body: nil, &block) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/muxi/transport.rb', line 65

def stream_lines(method, path, params: nil, body: nil, &block)
  url, full_path = build_url(path, params)
  headers = build_headers(method, full_path, accept: "text/event-stream")
  
  uri = URI.parse(url)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = uri.scheme == "https"
  http.read_timeout = nil # infinite for streaming

  request = build_request(method, uri, headers, body)
  
  http.request(request) do |response|
    response.read_body do |chunk|
      chunk.each_line do |line|
        yield line
      end
    end
  end
end