Class: Dalli::Server
- Inherits:
-
Object
- Object
- Dalli::Server
- Defined in:
- lib/dalli/server.rb
Constant Summary collapse
- 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 }
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.
-
#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.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/dalli/server.rb', line 34 def initialize(attribs, = {}) (@hostname, @port, @weight) = attribs.split(':') @port ||= 11211 @port = Integer(@port) @weight ||= 1 @weight = Integer(@weight) @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 |
#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
78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/dalli/server.rb', line 78 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 #{hostname}:#{port} (%.3f seconds left)" % time } return false end connect !!@sock rescue Dalli::NetworkError false end |
#close ⇒ Object
93 94 95 96 97 98 99 |
# File 'lib/dalli/server.rb', line 93 def close return unless @sock @sock.close rescue nil @sock = nil @pid = nil @inprogress = false end |
#compressor ⇒ Object
111 112 113 |
# File 'lib/dalli/server.rb', line 111 def compressor @options[:compressor] end |
#lock! ⇒ Object
101 102 |
# File 'lib/dalli/server.rb', line 101 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.
187 188 189 190 191 192 193 194 |
# File 'lib/dalli/server.rb', line 187 def multi_response_abort @multi_buffer = nil @position = nil @inprogress = false failure! rescue NetworkError true end |
#multi_response_completed? ⇒ Boolean
Did the last call to #multi_response_start complete successfully?
129 130 131 |
# File 'lib/dalli/server.rb', line 129 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.
139 140 141 142 143 144 145 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 |
# File 'lib/dalli/server.rb', line 139 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) = 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) rescue DalliError end else # not enough data yet, wait for more break end end @position = pos values rescue SystemCallError, Timeout::Error, EOFError failure! 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.
120 121 122 123 124 125 126 |
# File 'lib/dalli/server.rb', line 120 def multi_response_start verify_state write_noop @multi_buffer = '' @position = 0 @inprogress = true end |
#name ⇒ Object
51 52 53 |
# File 'lib/dalli/server.rb', line 51 def name "#{@hostname}:#{@port}" end |
#request(op, *args) ⇒ Object
Chokepoint method for instrumentation
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/dalli/server.rb', line 56 def request(op, *args) verify_state raise Dalli::NetworkError, "#{hostname}:#{port} is down: #{@error} #{@msg}" 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 => ex Dalli.logger.error "Unexpected exception in Dalli: #{ex.class.name}: #{ex.}" Dalli.logger.error "This is a bug in Dalli, please enter an issue in Github if it does not already exist." Dalli.logger.error ex.backtrace.join("\n\t") down! end end |
#serializer ⇒ Object
107 108 109 |
# File 'lib/dalli/server.rb', line 107 def serializer @options[:serializer] end |
#unlock! ⇒ Object
104 105 |
# File 'lib/dalli/server.rb', line 104 def unlock! end |