Class: Dalli::Server
- Inherits:
-
Object
- Object
- Dalli::Server
- Defined in:
- lib/dalli/server.rb
Defined Under Namespace
Modules: TCPSocketOptions Classes: NilObject
Constant Summary collapse
- DEFAULT_PORT =
11211
- DEFAULT_WEIGHT =
1
- DEFAULTS =
{ # seconds between trying to contact a remote server :down_retry_delay => 60, # connect/read/write timeout for socket operations :socket_timeout => 0.5, # times a socket operation may fail before considering the server dead :socket_max_failures => 2, # amount of time to sleep between retries when a failure occurs :socket_failure_delay => 0.01, # max size of value in bytes (default is 1 MB, can be overriden with "memcached -I <size>") :value_max_bytes => 1024 * 1024, # surpassing value_max_bytes either warns (false) or throws (true) :error_when_over_max_size => false, :compressor => Compressor, # min byte size to attempt compression :compression_min_size => 1024, # max byte size for compression :compression_max_size => false, :serializer => Marshal, :username => nil, :password => nil, :keepalive => true, # max byte size for SO_SNDBUF :sndbuf => nil, # max byte size for SO_RCVBUF :rcvbuf => nil }
Instance Attribute Summary collapse
-
#hostname ⇒ Object
Returns the value of attribute hostname.
-
#options ⇒ Object
Returns the value of attribute options.
-
#port ⇒ Object
Returns the value of attribute port.
-
#sock ⇒ Object
readonly
Returns the value of attribute sock.
-
#socket_type ⇒ Object
readonly
possible values: :unix, :tcp.
-
#weight ⇒ Object
Returns the value of attribute weight.
Instance Method Summary collapse
- #alive? ⇒ Boolean
- #close ⇒ Object
- #compressor ⇒ Object
-
#initialize(attribs, options = {}) ⇒ Server
constructor
A new instance of Server.
- #lock! ⇒ Object
-
#multi_response_abort ⇒ Object
Abort an earlier #multi_response_start.
-
#multi_response_completed? ⇒ Boolean
Did the last call to #multi_response_start complete successfully?.
-
#multi_response_nonblock ⇒ Object
Attempt to receive and parse as many key/value pairs as possible from this server.
-
#multi_response_start ⇒ Object
Start reading key/value pairs from this connection.
- #name ⇒ Object
-
#request(op, *args) ⇒ Object
Chokepoint method for instrumentation.
- #serializer ⇒ Object
- #unlock! ⇒ Object
Constructor Details
#initialize(attribs, options = {}) ⇒ Server
Returns a new instance of Server.
44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/dalli/server.rb', line 44 def initialize(attribs, = {}) @hostname, @port, @weight, @socket_type = parse_hostname(attribs) @fail_count = 0 @down_at = nil @last_down_at = nil @options = DEFAULTS.merge() @sock = nil @msg = nil @error = nil @pid = nil @inprogress = nil end |
Instance Attribute Details
#hostname ⇒ Object
Returns the value of attribute hostname.
7 8 9 |
# File 'lib/dalli/server.rb', line 7 def hostname @hostname end |
#options ⇒ Object
Returns the value of attribute options.
10 11 12 |
# File 'lib/dalli/server.rb', line 10 def @options end |
#port ⇒ Object
Returns the value of attribute port.
8 9 10 |
# File 'lib/dalli/server.rb', line 8 def port @port end |
#sock ⇒ Object (readonly)
Returns the value of attribute sock.
11 12 13 |
# File 'lib/dalli/server.rb', line 11 def sock @sock end |
#socket_type ⇒ Object (readonly)
possible values: :unix, :tcp
12 13 14 |
# File 'lib/dalli/server.rb', line 12 def socket_type @socket_type end |
#weight ⇒ Object
Returns the value of attribute weight.
9 10 11 |
# File 'lib/dalli/server.rb', line 9 def weight @weight end |
Instance Method Details
#alive? ⇒ Boolean
85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/dalli/server.rb', line 85 def alive? return true if @sock if @last_down_at && @last_down_at + [:down_retry_delay] >= Time.now time = @last_down_at + [:down_retry_delay] - Time.now Dalli.logger.debug { "down_retry_delay not reached for #{name} (%.3f seconds left)" % time } return false end connect !!@sock rescue Dalli::NetworkError false end |
#close ⇒ Object
100 101 102 103 104 105 106 |
# File 'lib/dalli/server.rb', line 100 def close return unless @sock @sock.close rescue nil @sock = nil @pid = nil @inprogress = false end |
#compressor ⇒ Object
118 119 120 |
# File 'lib/dalli/server.rb', line 118 def compressor @options[:compressor] end |
#lock! ⇒ Object
108 109 |
# File 'lib/dalli/server.rb', line 108 def lock! end |
#multi_response_abort ⇒ Object
Abort an earlier #multi_response_start. Used to signal an external timeout. The underlying socket is disconnected, and the exception is swallowed.
Returns nothing.
194 195 196 197 198 199 200 201 |
# File 'lib/dalli/server.rb', line 194 def multi_response_abort @multi_buffer = nil @position = nil @inprogress = false failure!(RuntimeError.new('External timeout')) rescue NetworkError true end |
#multi_response_completed? ⇒ Boolean
Did the last call to #multi_response_start complete successfully?
136 137 138 |
# File 'lib/dalli/server.rb', line 136 def multi_response_completed? @multi_buffer.nil? end |
#multi_response_nonblock ⇒ Object
Attempt to receive and parse as many key/value pairs as possible from this server. After #multi_response_start, this should be invoked repeatedly whenever this server’s socket is readable until #multi_response_completed?.
Returns a Hash of kv pairs received.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/dalli/server.rb', line 146 def multi_response_nonblock raise 'multi_response has completed' if @multi_buffer.nil? @multi_buffer << @sock.read_available buf = @multi_buffer pos = @position values = {} while buf.bytesize - pos >= 24 header = buf.slice(pos, 24) (key_length, _, body_length, cas) = header.unpack(KV_HEADER) if key_length == 0 # all done! @multi_buffer = nil @position = nil @inprogress = false break elsif buf.bytesize - pos >= 24 + body_length flags = buf.slice(pos + 24, 4).unpack('N')[0] key = buf.slice(pos + 24 + 4, key_length) value = buf.slice(pos + 24 + 4 + key_length, body_length - key_length - 4) if body_length - key_length - 4 > 0 pos = pos + 24 + body_length begin values[key] = [deserialize(value, flags), cas] rescue DalliError end else # not enough data yet, wait for more break end end @position = pos values rescue SystemCallError, Timeout::Error, EOFError => e failure!(e) end |
#multi_response_start ⇒ Object
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.
127 128 129 130 131 132 133 |
# File 'lib/dalli/server.rb', line 127 def multi_response_start verify_state write_noop @multi_buffer = String.new('') @position = 0 @inprogress = true end |
#name ⇒ Object
57 58 59 60 61 62 63 |
# File 'lib/dalli/server.rb', line 57 def name if socket_type == :unix hostname else "#{hostname}:#{port}" end end |
#request(op, *args) ⇒ Object
Chokepoint method for instrumentation
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/dalli/server.rb', line 66 def request(op, *args) verify_state raise Dalli::NetworkError, "#{name} is down: #{@error} #{@msg}. If you are sure it is running, ensure memcached version is > 1.4." unless alive? begin send(op, *args) rescue Dalli::MarshalError => ex Dalli.logger.error "Marshalling error for key '#{args.first}': #{ex.}" Dalli.logger.error "You are trying to cache a Ruby object which cannot be serialized to memcached." Dalli.logger.error ex.backtrace.join("\n\t") false rescue Dalli::DalliError, Dalli::NetworkError, Dalli::ValueOverMaxSize, Timeout::Error raise rescue => ex Dalli.logger.error "Unexpected exception during Dalli request: #{ex.class.name}: #{ex.}" Dalli.logger.error ex.backtrace.join("\n\t") down! end end |
#serializer ⇒ Object
114 115 116 |
# File 'lib/dalli/server.rb', line 114 def serializer @options[:serializer] end |
#unlock! ⇒ Object
111 112 |
# File 'lib/dalli/server.rb', line 111 def unlock! end |