Class: DiscordRDA::RestProxy

Inherits:
Object
  • Object
show all
Defined in:
lib/discord_rda/connection/rest_proxy.rb

Overview

REST Proxy for horizontal scaling. Allows multiple bot processes to share a single REST connection pool.

Defined Under Namespace

Classes: APIError, RateLimitedError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_url:, authorization:, logger: nil) ⇒ RestProxy

Initialize REST proxy client

Parameters:

  • base_url (String)

    Proxy base URL

  • authorization (String)

    Proxy authorization

  • logger (Logger) (defaults to: nil)

    Logger instance



24
25
26
27
28
29
30
31
# File 'lib/discord_rda/connection/rest_proxy.rb', line 24

def initialize(base_url:, authorization:, logger: nil)
  @base_url = base_url
  @authorization = authorization
  @logger = logger
  @connections = {}
  @mutex = Mutex.new
  @internet = nil
end

Instance Attribute Details

#authorizationString (readonly)

Returns Proxy authorization token.

Returns:

  • (String)

    Proxy authorization token



12
13
14
# File 'lib/discord_rda/connection/rest_proxy.rb', line 12

def authorization
  @authorization
end

#base_urlString (readonly)

Returns Proxy base URL.

Returns:

  • (String)

    Proxy base URL



9
10
11
# File 'lib/discord_rda/connection/rest_proxy.rb', line 9

def base_url
  @base_url
end

#connectionsHash (readonly)

Returns Active connections.

Returns:

  • (Hash)

    Active connections



18
19
20
# File 'lib/discord_rda/connection/rest_proxy.rb', line 18

def connections
  @connections
end

#loggerLogger (readonly)

Returns Logger instance.

Returns:

  • (Logger)

    Logger instance



15
16
17
# File 'lib/discord_rda/connection/rest_proxy.rb', line 15

def logger
  @logger
end

Instance Method Details

#forward(method, route, options = {}) ⇒ Hash

Forward a request to the proxy

Parameters:

  • method (Symbol)

    HTTP method

  • route (String)

    API route

  • options (Hash) (defaults to: {})

    Request options

Returns:

  • (Hash)

    Response data



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/discord_rda/connection/rest_proxy.rb', line 51

def forward(method, route, options = {})
  url = "#{@base_url}#{route}"

  headers = {
    'Authorization' => @authorization,
    'Content-Type' => 'application/json',
    'X-Proxy-Method' => method.to_s.upcase
  }.merge(options[:headers] || {})

  body = options[:body] ? Oj.dump(options[:body]) : nil

  response = case method
             when :get
               @internet.get(url, headers)
             when :post
               @internet.post(url, headers, body)
             when :put
               @internet.put(url, headers, body)
             when :patch
               @internet.patch(url, headers, body)
             when :delete
               @internet.delete(url, headers)
             end

  handle_response(response)
end

#health_checkHash

Get proxy health/status

Returns:

  • (Hash)

    Status information



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/discord_rda/connection/rest_proxy.rb', line 80

def health_check
  begin
    response = @internet.get("#{@base_url}/health", {})
    {
      healthy: response.status == 200,
      status: response.status,
      timestamp: Time.now.utc
    }
  rescue => e
    {
      healthy: false,
      error: e.message,
      timestamp: Time.now.utc
    }
  end
end

#register_bot(bot_id, token) ⇒ Hash

Register a bot instance with the proxy

Parameters:

  • bot_id (String)

    Bot ID

  • token (String)

    Bot token

Returns:

  • (Hash)

    Registration response



101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/discord_rda/connection/rest_proxy.rb', line 101

def register_bot(bot_id, token)
  response = @internet.post(
    "#{@base_url}/register",
    {
      'Authorization' => @authorization,
      'Content-Type' => 'application/json'
    },
    Oj.dump({ bot_id: bot_id, token: token })
  )

  handle_response(response)
end

#startvoid

This method returns an undefined value.

Start the proxy client



35
36
37
# File 'lib/discord_rda/connection/rest_proxy.rb', line 35

def start
  @internet = Async::HTTP::Internet.new
end

#stopvoid

This method returns an undefined value.

Stop the proxy client



41
42
43
44
# File 'lib/discord_rda/connection/rest_proxy.rb', line 41

def stop
  @internet&.close
  @internet = nil
end

#update_token(old_token, new_token) ⇒ void

This method returns an undefined value.

Update bearer token (for OAuth2 bots)

Parameters:

  • old_token (String)

    Old token

  • new_token (String)

    New token



118
119
120
121
122
123
124
125
126
127
# File 'lib/discord_rda/connection/rest_proxy.rb', line 118

def update_token(old_token, new_token)
  @internet.post(
    "#{@base_url}/update-token",
    {
      'Authorization' => @authorization,
      'Content-Type' => 'application/json'
    },
    Oj.dump({ old_token: old_token, new_token: new_token })
  )
end