Class: Gruf::Balancer::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/gruf/balancer/client.rb

Overview

Thread-safe class that allows percentage-based balancing of calls to a given pool of clients

Instance Method Summary collapse

Constructor Details

#initialize(service:, options: {}, client_options: {}) ⇒ Client

Returns a new instance of Client.

Parameters:

  • service (GRPC::GenericService)

    The gRPC Service stub to use when creating clients in this pool

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

    A default set of options to pass through to all Gruf::Clients in this balanced pool

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

    A default set of gRPC client options to pass through to all Gruf::Clients in this balanced pool


30
31
32
33
34
35
36
37
# File 'lib/gruf/balancer/client.rb', line 30

def initialize(service:, options: {}, client_options: {})
  super()
  @service = service
  @options = options
  @client_options = client_options
  @pool = ::Concurrent::Hash.new
  @sampler = ->(pool) { pool.max_by { |_, w| rand**(1.0 / w) }.first }
end

Instance Method Details

#add_client(percentage:, options: {}, client_options: {}, client_class: nil) ⇒ Object

Create a client and add it to the pool at a given percentage of requests. If the percentage given is outside of 0-100, it will automatically constrain it to the max of 100.0 or minimum of 0.0.

Parameters:

  • percentage (Float)

    The percentage of requests to weight by (0-100)

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

    Options to pass-through to the Gruf::Client

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

    gRPC Client Options to pass-through to the Gruf::Client

  • client_class (Class) (defaults to: nil)

    The client class to use. Useful if wanting to create a Gruf::SynchronizedClient or other derivative client


49
50
51
52
53
54
55
56
57
58
59
# File 'lib/gruf/balancer/client.rb', line 49

def add_client(percentage:, options: {}, client_options: {}, client_class: nil)
  client_class ||= ::Gruf::Client
  percentage = percentage > 100.0 ? 100.0 : percentage.to_f
  percentage = percentage < 0.0 ? 0.0 : percentage
  cl = client_class.new(
    service: @service,
    options: @options.merge(options),
    client_options: @client_options.merge(client_options)
  )
  @pool[cl] = percentage.to_f / 100.0
end

#call(*args, &block) ⇒ Gruf::Response

Delegate the call to the sampled client

Returns:

  • (Gruf::Response)

75
76
77
# File 'lib/gruf/balancer/client.rb', line 75

def call(*args, &block)
  pick.call(*args, &block)
end

#pick::Gruf::Client

Pick a sampled client from the pool based on the weighted percentages entered

Returns:

  • (::Gruf::Client)

66
67
68
# File 'lib/gruf/balancer/client.rb', line 66

def pick
  @sampler[@pool]
end