Sha256: 05b8ca51ca82bdc56a3aba6521b9f33197b1bdbcab414ea149ce8e61783c1509

Contents?: true

Size: 1.87 KB

Versions: 6

Compression:

Stored size: 1.87 KB

Contents

class Etcdv3
  class ConnectionWrapper

    attr_accessor :connection, :endpoints, :user, :password, :token, :timeout

    def initialize(timeout, *endpoints)
      @user, @password, @token = nil, nil, nil
      @timeout = timeout
      @endpoints = endpoints.map{|endpoint| Etcdv3::Connection.new(endpoint, @timeout) }
      @connection = @endpoints.first
    end

    def handle(stub, method, method_args=[], retries: 1)
      @connection.call(stub, method, method_args)

    rescue GRPC::Unavailable, GRPC::Core::CallError => exception
      $stderr.puts("Failed to connect to endpoint '#{@connection.hostname}'")
      if @endpoints.size > 1
        rotate_connection_endpoint
        $stderr.puts("Failover event triggered. Failing over to '#{@connection.hostname}'")
        return handle(stub, method, method_args)
      else
        return handle(stub, method, method_args)
      end
    rescue GRPC::Unauthenticated => exception
      # Regenerate token in the event it expires.
      if exception.details == 'etcdserver: invalid auth token'
        if retries > 0
          authenticate(@user, @password)
          return handle(stub, method, method_args, retries: retries - 1)
        end
      end
      raise exception
    end

    def clear_authentication
      @user, @password, @token = nil, nil, nil
      @connection.refresh_metadata({})
    end

    # Authenticate using specified user and password..
    def authenticate(user, password)
      @token = handle(:auth, 'generate_token', [user, password])
      @user, @password = user, password
      @connection.refresh_metadata(token: @token)
    end

    # Simple failover mechanism that rotates the connection endpoints in an
    # attempt to recover connectivity.
    def rotate_connection_endpoint
      @endpoints.rotate!
      @connection = @endpoints.first
      @connection.refresh_metadata(token: @token) if @token
    end
  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
etcdv3-0.10.1 lib/etcdv3/connection_wrapper.rb
etcdv3-0.9.0 lib/etcdv3/connection_wrapper.rb
etcdv3-0.8.3 lib/etcdv3/connection_wrapper.rb
etcdv3-0.8.2 lib/etcdv3/connection_wrapper.rb
etcdv3-0.8.1 lib/etcdv3/connection_wrapper.rb
etcdv3-0.8.0 lib/etcdv3/connection_wrapper.rb