Class: Dalli::Protocol::Base

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/dalli/protocol/base.rb

Overview

Base class for a single Memcached server, containing logic common to all protocols. Contains logic for managing connection state to the server and value handling.

Direct Known Subclasses

Binary, Meta

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Base.



23
24
25
26
27
28
# File 'lib/dalli/protocol/base.rb', line 23

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)
end

Instance Attribute Details

#optionsObject

Returns the value of attribute options.



17
18
19
# File 'lib/dalli/protocol/base.rb', line 17

def options
  @options
end

#weightObject

Returns the value of attribute weight.



17
18
19
# File 'lib/dalli/protocol/base.rb', line 17

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)


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

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



65
# File 'lib/dalli/protocol/base.rb', line 65

def lock!; end

#passwordObject



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

def password
  @options[:password] || ENV.fetch('MEMCACHE_PASSWORD', nil)
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/base.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/base.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/base.rb', line 86

def pipeline_next_responses
  reconnect_on_pipeline_complete!
  values = {}

  response_buffer.read

  status, cas, key, value = response_buffer.process_single_getk_response
  # status is not nil only if we have a full response to parse
  # in the buffer
  until status.nil?
    # 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 status && 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, cas] unless key.nil?

    # Get the next response from the buffer
    status, cas, key, value = response_buffer.process_single_getk_response
  end

  values
rescue SystemCallError, *TIMEOUT_ERRORS, 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.



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

def pipeline_response_setup
  verify_pipelined_state(:getkq)
  write_noop
  response_buffer.reset
end

#quiet?Boolean Also known as: multi?

Returns:

  • (Boolean)


147
148
149
# File 'lib/dalli/protocol/base.rb', line 147

def quiet?
  Thread.current[::Dalli::QUIET]
end

#request(opkey, *args) ⇒ Object

Chokepoint method for error handling and ensuring liveness



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/dalli/protocol/base.rb', line 31

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

  begin
    @connection_manager.start_request!
    response = send(opkey, *args)

    # pipelined_get emit query but doesn't read the response(s)
    @connection_manager.finish_request! unless opkey == :pipelined_get

    response
  rescue Dalli::MarshalError => e
    log_marshal_err(args.first, e)
    raise
  rescue Dalli::DalliError
    raise
  rescue StandardError => e
    log_unexpected_err(e)
    close
    raise
  end
end

#require_auth?Boolean

Returns:

  • (Boolean)


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

def require_auth?
  !username.nil?
end

#unlock!Object



67
# File 'lib/dalli/protocol/base.rb', line 67

def unlock!; end

#usernameObject



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

def username
  @options[:username] || ENV.fetch('MEMCACHE_USERNAME', nil)
end