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 => 1, # 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, :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.
41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/dalli/server.rb', line 41 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.
6 7 8 |
# File 'lib/dalli/server.rb', line 6 def hostname @hostname end |
#options ⇒ Object
Returns the value of attribute options.
9 10 11 |
# File 'lib/dalli/server.rb', line 9 def @options end |
#port ⇒ Object
Returns the value of attribute port.
7 8 9 |
# File 'lib/dalli/server.rb', line 7 def port @port end |
#sock ⇒ Object (readonly)
Returns the value of attribute sock.
10 11 12 |
# File 'lib/dalli/server.rb', line 10 def sock @sock end |
#socket_type ⇒ Object (readonly)
possible values: :unix, :tcp
11 12 13 |
# File 'lib/dalli/server.rb', line 11 def socket_type @socket_type end |
#weight ⇒ Object
Returns the value of attribute weight.
8 9 10 |
# File 'lib/dalli/server.rb', line 8 def weight @weight end |
Instance Method Details
#alive? ⇒ Boolean
86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/dalli/server.rb', line 86 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
101 102 103 104 105 106 107 |
# File 'lib/dalli/server.rb', line 101 def close return unless @sock @sock.close rescue nil @sock = nil @pid = nil @inprogress = false end |
#compressor ⇒ Object
119 120 121 |
# File 'lib/dalli/server.rb', line 119 def compressor @options[:compressor] end |
#lock! ⇒ Object
109 110 |
# File 'lib/dalli/server.rb', line 109 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.
195 196 197 198 199 200 201 202 |
# File 'lib/dalli/server.rb', line 195 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?
137 138 139 |
# File 'lib/dalli/server.rb', line 137 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.
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 188 |
# File 'lib/dalli/server.rb', line 147 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.
128 129 130 131 132 133 134 |
# File 'lib/dalli/server.rb', line 128 def multi_response_start verify_state write_noop @multi_buffer = '' @position = 0 @inprogress = true end |
#name ⇒ Object
54 55 56 57 58 59 60 |
# File 'lib/dalli/server.rb', line 54 def name if socket_type == :unix hostname else "#{hostname}:#{port}" end end |
#request(op, *args) ⇒ Object
Chokepoint method for instrumentation
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/dalli/server.rb', line 63 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::NetworkError raise 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 raise rescue 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
115 116 117 |
# File 'lib/dalli/server.rb', line 115 def serializer @options[:serializer] end |
#unlock! ⇒ Object
112 113 |
# File 'lib/dalli/server.rb', line 112 def unlock! end |