Class: Dalli::Protocol::Binary

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
SaslAuthentication
Defined in:
lib/dalli/protocol/binary.rb,
lib/dalli/protocol/binary/response_header.rb,
lib/dalli/protocol/binary/request_formatter.rb,
lib/dalli/protocol/binary/response_processor.rb,
lib/dalli/protocol/binary/sasl_authentication.rb

Overview

Access point for a single Memcached server, accessed via Memcached’s binary protocol. Contains logic for managing connection state to the server (retries, etc), formatting requests to the server, and unpacking responses.

Defined Under Namespace

Modules: SaslAuthentication Classes: RequestFormatter, ResponseHeader, ResponseProcessor

Constant Summary

Constants included from SaslAuthentication

SaslAuthentication::PLAIN_AUTH

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SaslAuthentication

#authenticate_connection, #authenticate_with_plain, #perform_auth_negotiation, #supported_mechanisms!

Constructor Details

#initialize(attribs, client_options = {}) ⇒ Binary

Returns a new instance of Binary.



28
29
30
31
32
33
34
# File 'lib/dalli/protocol/binary.rb', line 28

def initialize(attribs, client_options = {})
  hostname, port, socket_type, @weight, user_creds = ServerConfigParser.parse(attribs)
  @options = client_options.merge(user_creds)
  @value_marshaller = ValueMarshaller.new(@options)
  @connection_manager = ConnectionManager.new(hostname, port, socket_type, @options)
  @response_processor = ResponseProcessor.new(@connection_manager, @value_marshaller)
end

Instance Attribute Details

#optionsObject

Returns the value of attribute options.



22
23
24
# File 'lib/dalli/protocol/binary.rb', line 22

def options
  @options
end

#weightObject

Returns the value of attribute weight.



22
23
24
# File 'lib/dalli/protocol/binary.rb', line 22

def weight
  @weight
end

Instance Method Details

#alive?Boolean

Boolean method used by clients of this class to determine if this particular memcached instance is available for use.

Returns:

  • (Boolean)


56
57
58
59
60
61
62
# File 'lib/dalli/protocol/binary.rb', line 56

def alive?
  ensure_connected!
rescue Dalli::NetworkError
  # ensure_connected! raises a NetworkError if connection fails.  We
  # want to capture that error and convert it to a boolean value here.
  false
end

#lock!Object



64
# File 'lib/dalli/protocol/binary.rb', line 64

def lock!; end

#passwordObject



139
140
141
# File 'lib/dalli/protocol/binary.rb', line 139

def password
  @options[:password] || ENV['MEMCACHE_PASSWORD']
end

#pipeline_abortObject

Abort current pipelined get. Generally used to signal an external timeout during pipelined get. The underlying socket is disconnected, and the exception is swallowed.

Returns nothing.



118
119
120
121
122
123
124
125
126
127
128
# File 'lib/dalli/protocol/binary.rb', line 118

def pipeline_abort
  response_buffer.clear
  @connection_manager.abort_request!
  return true unless connected?

  # Closes the connection, which ensures that our connection
  # is in a clean state for future requests
  @connection_manager.error_on_request!('External timeout')
rescue NetworkError
  true
end

#pipeline_complete?Boolean

Did the last call to #pipeline_response_setup complete successfully?

Returns:

  • (Boolean)


131
132
133
# File 'lib/dalli/protocol/binary.rb', line 131

def pipeline_complete?
  !response_buffer.in_progress?
end

#pipeline_next_responsesObject

Attempt to receive and parse as many key/value pairs as possible from this server. After #pipeline_response_setup, this should be invoked repeatedly whenever this server’s socket is readable until #pipeline_complete?.

Returns a Hash of kv pairs received.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/dalli/protocol/binary.rb', line 86

def pipeline_next_responses
  reconnect_on_pipeline_complete!
  values = {}

  response_buffer.read

  resp_header, key, value = pipeline_response
  # resp_header is not nil only if we have a full response to parse
  # in the buffer
  while resp_header
    # If the status is ok and key is nil, then this is the response
    # to the noop at the end of the pipeline
    finish_pipeline && break if resp_header.ok? && key.nil?

    # If the status is ok and the key is not nil, then this is a
    # getkq response with a value that we want to set in the response hash
    values[key] = [value, resp_header.cas] unless key.nil?

    # Get the next response from the buffer
    resp_header, key, value = pipeline_response
  end

  values
rescue SystemCallError, Timeout::Error, EOFError => e
  @connection_manager.error_on_request!(e)
end

#pipeline_response_setupObject

Start reading key/value pairs from this connection. This is usually called after a series of GETKQ commands. A NOOP is sent, and the server begins flushing responses for kv pairs that were found.

Returns nothing.



73
74
75
76
77
78
# File 'lib/dalli/protocol/binary.rb', line 73

def pipeline_response_setup
  verify_state(:getkq)
  write_noop
  response_buffer.reset
  @connection_manager.start_request!
end

#request(opkey, *args) ⇒ Object

Chokepoint method for error handling and ensuring liveness



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/dalli/protocol/binary.rb', line 37

def request(opkey, *args)
  verify_state(opkey)

  begin
    send(opkey, *args)
  rescue Dalli::MarshalError => e
    log_marshal_err(args.first, e)
    raise
  rescue Dalli::DalliError
    raise
  rescue StandardError => e
    log_unexpected_err(e)
    down!
  end
end

#require_auth?Boolean

Returns:

  • (Boolean)


143
144
145
# File 'lib/dalli/protocol/binary.rb', line 143

def require_auth?
  !username.nil?
end

#unlock!Object



66
# File 'lib/dalli/protocol/binary.rb', line 66

def unlock!; end

#usernameObject



135
136
137
# File 'lib/dalli/protocol/binary.rb', line 135

def username
  @options[:username] || ENV['MEMCACHE_USERNAME']
end