dalli 2.7.0 → 3.0.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of dalli might be problematic. Click here for more details.

data/lib/dalli/socket.rb CHANGED
@@ -1,108 +1,104 @@
1
- begin
2
- require 'kgio'
3
- puts "Using kgio socket IO" if defined?($TESTING) && $TESTING
1
+ # frozen_string_literal: true
4
2
 
5
- class Dalli::Server::KSocket < Kgio::Socket
6
- attr_accessor :options, :server
3
+ require 'openssl'
4
+ require 'rbconfig'
7
5
 
8
- def kgio_wait_readable
9
- IO.select([self], nil, nil, options[:socket_timeout]) || raise(Timeout::Error, "IO timeout")
10
- end
11
-
12
- def kgio_wait_writable
13
- IO.select(nil, [self], nil, options[:socket_timeout]) || raise(Timeout::Error, "IO timeout")
14
- end
6
+ module Dalli
7
+ module Socket
8
+ module InstanceMethods
15
9
 
16
- def self.open(host, port, server, options = {})
17
- addr = Socket.pack_sockaddr_in(port, host)
18
- sock = start(addr)
19
- sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, true)
20
- sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true) if options[:keepalive]
21
- sock.options = options
22
- sock.server = server
23
- sock.kgio_wait_writable
24
- sock
25
- end
10
+ def readfull(count)
11
+ value = +""
12
+ loop do
13
+ result = read_nonblock(count - value.bytesize, exception: false)
14
+ if result == :wait_readable
15
+ raise Timeout::Error, "IO timeout: #{safe_options.inspect}" unless IO.select([self], nil, nil, options[:socket_timeout])
16
+ elsif result == :wait_writable
17
+ raise Timeout::Error, "IO timeout: #{safe_options.inspect}" unless IO.select(nil, [self], nil, options[:socket_timeout])
18
+ elsif result
19
+ value << result
20
+ else
21
+ raise Errno::ECONNRESET, "Connection reset: #{safe_options.inspect}"
22
+ end
23
+ break if value.bytesize == count
24
+ end
25
+ value
26
+ end
26
27
 
27
- alias :write :kgio_write
28
+ def read_available
29
+ value = +""
30
+ loop do
31
+ result = read_nonblock(8196, exception: false)
32
+ if result == :wait_readable
33
+ break
34
+ elsif result == :wait_writable
35
+ break
36
+ elsif result
37
+ value << result
38
+ else
39
+ raise Errno::ECONNRESET, "Connection reset: #{safe_options.inspect}"
40
+ end
41
+ end
42
+ value
43
+ end
28
44
 
29
- def readfull(count)
30
- value = ''
31
- loop do
32
- value << kgio_read!(count - value.bytesize)
33
- break if value.bytesize == count
45
+ def safe_options
46
+ options.reject { |k, v| [:username, :password].include? k }
34
47
  end
35
- value
36
48
  end
37
49
 
38
- def read_available
39
- value = ''
40
- loop do
41
- ret = kgio_tryread(8196)
42
- case ret
43
- when nil
44
- raise EOFError, 'end of stream'
45
- when :wait_readable
46
- break
47
- else
48
- value << ret
49
- end
50
+ class SSLSocket < ::OpenSSL::SSL::SSLSocket
51
+ include Dalli::Socket::InstanceMethods
52
+ def options
53
+ io.options
50
54
  end
51
- value
52
55
  end
53
56
 
54
- end
55
-
56
- if ::Kgio.respond_to?(:wait_readable=)
57
- ::Kgio.wait_readable = :kgio_wait_readable
58
- ::Kgio.wait_writable = :kgio_wait_writable
59
- end
57
+ class TCP < TCPSocket
58
+ include Dalli::Socket::InstanceMethods
59
+ attr_accessor :options, :server
60
60
 
61
- rescue LoadError
61
+ def self.open(host, port, server, options = {})
62
+ Timeout.timeout(options[:socket_timeout]) do
63
+ sock = new(host, port)
64
+ sock.options = {host: host, port: port}.merge(options)
65
+ sock.server = server
66
+ sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, true)
67
+ sock.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_KEEPALIVE, true) if options[:keepalive]
68
+ sock.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_RCVBUF, options[:rcvbuf]) if options[:rcvbuf]
69
+ sock.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_SNDBUF, options[:sndbuf]) if options[:sndbuf]
62
70
 
63
- puts "Using standard socket IO (#{RUBY_DESCRIPTION})" if defined?($TESTING) && $TESTING
64
- class Dalli::Server::KSocket < TCPSocket
65
- attr_accessor :options, :server
71
+ return sock unless options[:ssl_context]
66
72
 
67
- def self.open(host, port, server, options = {})
68
- Timeout.timeout(options[:socket_timeout]) do
69
- sock = new(host, port)
70
- sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, true)
71
- sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true) if options[:keepalive]
72
- sock.options = { :host => host, :port => port }.merge(options)
73
- sock.server = server
74
- sock
73
+ ssl_socket = Dalli::Socket::SSLSocket.new(sock, options[:ssl_context])
74
+ ssl_socket.hostname = host
75
+ ssl_socket.sync_close = true
76
+ ssl_socket.connect
77
+ ssl_socket
78
+ end
75
79
  end
76
80
  end
81
+ end
77
82
 
78
- def readfull(count)
79
- value = ''
80
- begin
81
- loop do
82
- value << read_nonblock(count - value.bytesize)
83
- break if value.bytesize == count
84
- end
85
- rescue Errno::EAGAIN, Errno::EWOULDBLOCK
86
- if IO.select([self], nil, nil, options[:socket_timeout])
87
- retry
88
- else
89
- raise Timeout::Error, "IO timeout: #{options.inspect}"
90
- end
83
+ if RbConfig::CONFIG['host_os'] =~ /mingw|mswin/
84
+ class Dalli::Socket::UNIX
85
+ def initialize(*args)
86
+ raise Dalli::DalliError, 'Unix sockets are not supported on Windows platform.'
91
87
  end
92
- value
93
88
  end
89
+ else
90
+ class Dalli::Socket::UNIX < UNIXSocket
91
+ include Dalli::Socket::InstanceMethods
92
+ attr_accessor :options, :server
94
93
 
95
- def read_available
96
- value = ''
97
- loop do
98
- begin
99
- value << read_nonblock(8196)
100
- rescue Errno::EAGAIN, Errno::EWOULDBLOCK
101
- break
94
+ def self.open(path, server, options = {})
95
+ Timeout.timeout(options[:socket_timeout]) do
96
+ sock = new(path)
97
+ sock.options = {path: path}.merge(options)
98
+ sock.server = server
99
+ sock
102
100
  end
103
101
  end
104
- value
105
102
  end
106
-
107
103
  end
108
104
  end
data/lib/dalli/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dalli
2
- VERSION = '2.7.0'
4
+ VERSION = "3.0.4"
3
5
  end
data/lib/dalli.rb CHANGED
@@ -1,13 +1,20 @@
1
- require 'dalli/compressor'
2
- require 'dalli/client'
3
- require 'dalli/ring'
4
- require 'dalli/server'
5
- require 'dalli/socket'
6
- require 'dalli/version'
7
- require 'dalli/options'
8
- require 'dalli/railtie' if defined?(::Rails::Railtie)
1
+ # frozen_string_literal: true
2
+
3
+ require "dalli/compressor"
4
+ require "dalli/client"
5
+ require "dalli/ring"
6
+ require "dalli/protocol"
7
+ require "dalli/protocol/binary"
8
+ require "dalli/protocol/server_config_parser"
9
+ require "dalli/protocol/ttl_sanitizer"
10
+ require 'dalli/protocol/value_compressor'
11
+ require "dalli/socket"
12
+ require "dalli/version"
13
+ require "dalli/options"
9
14
 
10
15
  module Dalli
16
+ autoload :Server, "dalli/server"
17
+
11
18
  # generic error
12
19
  class DalliError < RuntimeError; end
13
20
  # socket/server communication error
@@ -18,6 +25,8 @@ module Dalli
18
25
  class MarshalError < DalliError; end
19
26
  # application error in marshalling deserialization or decompression
20
27
  class UnmarshalError < DalliError; end
28
+ # payload too big for memcached
29
+ class ValueOverMaxSize < DalliError; end
21
30
 
22
31
  def self.logger
23
32
  @logger ||= (rails_logger || default_logger)
@@ -25,12 +34,12 @@ module Dalli
25
34
 
26
35
  def self.rails_logger
27
36
  (defined?(Rails) && Rails.respond_to?(:logger) && Rails.logger) ||
28
- (defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:debug) && RAILS_DEFAULT_LOGGER)
37
+ (defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:debug) && RAILS_DEFAULT_LOGGER)
29
38
  end
30
39
 
31
40
  def self.default_logger
32
- require 'logger'
33
- l = Logger.new(STDOUT)
41
+ require "logger"
42
+ l = Logger.new($stdout)
34
43
  l.level = Logger::INFO
35
44
  l
36
45
  end
@@ -38,9 +47,4 @@ module Dalli
38
47
  def self.logger=(logger)
39
48
  @logger = logger
40
49
  end
41
-
42
- end
43
-
44
- if defined?(RAILS_VERSION) && RAILS_VERSION < '3'
45
- raise Dalli::DalliError, "Dalli #{Dalli::VERSION} does not support Rails version < 3.0"
46
50
  end
@@ -1,36 +1,92 @@
1
+ # frozen_string_literal: true
1
2
  require 'rack/session/abstract/id'
2
3
  require 'dalli'
4
+ require 'connection_pool'
3
5
 
4
6
  module Rack
5
7
  module Session
6
- class Dalli < Abstract::ID
7
- attr_reader :pool, :mutex
8
+ class Dalli < Abstract::Persisted
9
+ attr_reader :pool
8
10
 
9
- DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge \
11
+ DEFAULT_DALLI_OPTIONS = {
10
12
  :namespace => 'rack:session',
11
13
  :memcache_server => 'localhost:11211'
14
+ }
12
15
 
16
+ # Brings in a new Rack::Session::Dalli middleware with the given
17
+ # `:memcache_server`. The server is either a hostname, or a
18
+ # host-with-port string in the form of "host_name:port", or an array of
19
+ # such strings. For example:
20
+ #
21
+ # use Rack::Session::Dalli,
22
+ # :memcache_server => "mc.example.com:1234"
23
+ #
24
+ # If no `:memcache_server` option is specified, Rack::Session::Dalli will
25
+ # connect to localhost, port 11211 (the default memcached port). If
26
+ # `:memcache_server` is set to nil, Dalli::Client will look for
27
+ # ENV['MEMCACHE_SERVERS'] and use that value if it is available, or fall
28
+ # back to the same default behavior described above.
29
+ #
30
+ # Rack::Session::Dalli is intended to be a drop-in replacement for
31
+ # Rack::Session::Memcache. It accepts additional options that control the
32
+ # behavior of Rack::Session, Dalli::Client, and an optional
33
+ # ConnectionPool. First and foremost, if you wish to instantiate your own
34
+ # Dalli::Client (or ConnectionPool) and use that instead of letting
35
+ # Rack::Session::Dalli instantiate it on your behalf, simply pass it in
36
+ # as the `:cache` option. Please note that you will be responsible for
37
+ # setting the namespace and any other options on Dalli::Client.
38
+ #
39
+ # Secondly, if you're not using the `:cache` option, Rack::Session::Dalli
40
+ # accepts the same options as Dalli::Client, so it's worth reviewing its
41
+ # documentation. Perhaps most importantly, if you don't specify a
42
+ # `:namespace` option, Rack::Session::Dalli will default to using
43
+ # "rack:session".
44
+ #
45
+ # Whether you are using the `:cache` option or not, it is not recommend
46
+ # to set `:expires_in`. Instead, use `:expire_after`, which will control
47
+ # both the expiration of the client cookie as well as the expiration of
48
+ # the corresponding entry in memcached.
49
+ #
50
+ # Rack::Session::Dalli also accepts a host of options that control how
51
+ # the sessions and session cookies are managed, including the
52
+ # aforementioned `:expire_after` option. Please see the documentation for
53
+ # Rack::Session::Abstract::Persisted for a detailed explanation of these
54
+ # options and their default values.
55
+ #
56
+ # Finally, if your web application is multithreaded, the
57
+ # Rack::Session::Dalli middleware can become a source of contention. You
58
+ # can use a connection pool of Dalli clients by passing in the
59
+ # `:pool_size` and/or `:pool_timeout` options. For example:
60
+ #
61
+ # use Rack::Session::Dalli,
62
+ # :memcache_server => "mc.example.com:1234",
63
+ # :pool_size => 10
64
+ #
65
+ # You must include the `connection_pool` gem in your project if you wish
66
+ # to use pool support. Please see the documentation for ConnectionPool
67
+ # for more information about it and its default options (which would only
68
+ # be applicable if you supplied one of the two options, but not both).
69
+ #
13
70
  def initialize(app, options={})
71
+ # Parent uses DEFAULT_OPTIONS to build @default_options for Rack::Session
14
72
  super
15
- @mutex = Mutex.new
16
- mserv = @default_options[:memcache_server]
17
- mopts = @default_options.reject{|k,v| !DEFAULT_OPTIONS.include? k }
18
- @pool = options[:cache] || ::Dalli::Client.new(mserv, mopts)
19
- end
20
73
 
21
- def generate_sid
22
- loop do
23
- sid = super
24
- break sid unless @pool.get(sid)
25
- end
74
+ # Determine the default TTL for newly-created sessions
75
+ @default_ttl = ttl @default_options[:expire_after]
76
+
77
+ # Normalize and validate passed options
78
+ mserv, mopts, popts = extract_dalli_options(options)
79
+
80
+ @pool = ConnectionPool.new(popts || {}) { ::Dalli::Client.new(mserv, mopts) }
26
81
  end
27
82
 
28
83
  def get_session(env, sid)
29
- with_lock(env, [nil, {}]) do
30
- unless sid and session = @pool.get(sid)
31
- sid, session = generate_sid, {}
32
- unless @pool.add(sid, session)
33
- raise "Session collision on '#{sid.inspect}'"
84
+ with_block([nil, {}]) do |dc|
85
+ unless sid and !sid.empty? and session = dc.get(sid)
86
+ old_sid, sid, session = sid, generate_sid_with(dc), {}
87
+ unless dc.add(sid, session, @default_ttl)
88
+ sid = old_sid
89
+ redo # generate a new sid and try again
34
90
  end
35
91
  end
36
92
  [sid, session]
@@ -38,25 +94,62 @@ module Rack
38
94
  end
39
95
 
40
96
  def set_session(env, session_id, new_session, options)
41
- expiry = options[:expire_after]
42
- expiry = expiry.nil? ? 0 : expiry + 1
97
+ return false unless session_id
43
98
 
44
- with_lock(env, false) do
45
- @pool.set session_id, new_session, expiry
99
+ with_block(false) do |dc|
100
+ dc.set(session_id, new_session, ttl(options[:expire_after]))
46
101
  session_id
47
102
  end
48
103
  end
49
104
 
50
105
  def destroy_session(env, session_id, options)
51
- with_lock(env) do
52
- @pool.delete(session_id)
53
- generate_sid unless options[:drop]
106
+ with_block do |dc|
107
+ dc.delete(session_id)
108
+ generate_sid_with(dc) unless options[:drop]
54
109
  end
55
110
  end
56
111
 
57
- def with_lock(env, default=nil)
58
- @mutex.lock if env['rack.multithread']
59
- yield
112
+ def find_session(req, sid)
113
+ get_session req.env, sid
114
+ end
115
+
116
+ def write_session(req, sid, session, options)
117
+ set_session req.env, sid, session, options
118
+ end
119
+
120
+ def delete_session(req, sid, options)
121
+ destroy_session req.env, sid, options
122
+ end
123
+
124
+ private
125
+
126
+ def extract_dalli_options(options)
127
+ raise "Rack::Session::Dalli no longer supports the :cache option." if options[:cache]
128
+
129
+ popts = {}
130
+ # Filter out Rack::Session-specific options and apply our defaults
131
+ mopts = DEFAULT_DALLI_OPTIONS.merge \
132
+ options.reject {|k, _| DEFAULT_OPTIONS.key? k }
133
+ mserv = mopts.delete :memcache_server
134
+
135
+ if mopts[:pool_size] || mopts[:pool_timeout]
136
+ popts[:size] = mopts.delete :pool_size if mopts[:pool_size]
137
+ popts[:timeout] = mopts.delete :pool_timeout if mopts[:pool_timeout]
138
+ mopts[:threadsafe] = true
139
+ end
140
+
141
+ [mserv, mopts, popts]
142
+ end
143
+
144
+ def generate_sid_with(dc)
145
+ while true
146
+ sid = generate_sid
147
+ break sid unless dc.get(sid)
148
+ end
149
+ end
150
+
151
+ def with_block(default=nil, &block)
152
+ @pool.with(&block)
60
153
  rescue ::Dalli::DalliError, Errno::ECONNREFUSED
61
154
  raise if $!.message =~ /undefined class/
62
155
  if $VERBOSE
@@ -64,10 +157,11 @@ module Rack
64
157
  warn $!.inspect
65
158
  end
66
159
  default
67
- ensure
68
- @mutex.unlock if @mutex.locked?
69
160
  end
70
161
 
162
+ def ttl(expire_after)
163
+ expire_after.nil? ? 0 : expire_after + 1
164
+ end
71
165
  end
72
166
  end
73
167
  end
metadata CHANGED
@@ -1,136 +1,92 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dalli
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 3.0.4
5
5
  platform: ruby
6
6
  authors:
7
+ - Peter M. Goldstein
7
8
  - Mike Perham
8
- autorequire:
9
+ autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2014-01-07 00:00:00.000000000 Z
12
+ date: 2021-10-27 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
- name: minitest
15
+ name: rack
15
16
  requirement: !ruby/object:Gem::Requirement
16
17
  requirements:
17
- - - '>='
18
- - !ruby/object:Gem::Version
19
- version: 4.2.0
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - '>='
25
- - !ruby/object:Gem::Version
26
- version: 4.2.0
27
- - !ruby/object:Gem::Dependency
28
- name: mocha
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '>='
18
+ - - ">="
32
19
  - !ruby/object:Gem::Version
33
20
  version: '0'
34
21
  type: :development
35
22
  prerelease: false
36
23
  version_requirements: !ruby/object:Gem::Requirement
37
24
  requirements:
38
- - - '>='
25
+ - - ">="
39
26
  - !ruby/object:Gem::Version
40
27
  version: '0'
41
28
  - !ruby/object:Gem::Dependency
42
- name: rails
29
+ name: connection_pool
43
30
  requirement: !ruby/object:Gem::Requirement
44
31
  requirements:
45
- - - ~>
32
+ - - ">="
46
33
  - !ruby/object:Gem::Version
47
- version: '3'
34
+ version: '0'
48
35
  type: :development
49
36
  prerelease: false
50
37
  version_requirements: !ruby/object:Gem::Requirement
51
38
  requirements:
52
- - - ~>
39
+ - - ">="
53
40
  - !ruby/object:Gem::Version
54
- version: '3'
41
+ version: '0'
55
42
  description: High performance memcached client for Ruby
56
- email: mperham@gmail.com
43
+ email:
44
+ - peter.m.goldstein@gmail.com
45
+ - mperham@gmail.com
57
46
  executables: []
58
47
  extensions: []
59
48
  extra_rdoc_files: []
60
49
  files:
61
- - lib/action_dispatch/middleware/session/dalli_store.rb
62
- - lib/active_support/cache/dalli_store.rb
50
+ - Gemfile
51
+ - History.md
52
+ - LICENSE
53
+ - README.md
54
+ - lib/dalli.rb
63
55
  - lib/dalli/cas/client.rb
64
56
  - lib/dalli/client.rb
65
57
  - lib/dalli/compressor.rb
66
58
  - lib/dalli/options.rb
67
- - lib/dalli/railtie.rb
59
+ - lib/dalli/protocol.rb
60
+ - lib/dalli/protocol/binary.rb
61
+ - lib/dalli/protocol/server_config_parser.rb
62
+ - lib/dalli/protocol/ttl_sanitizer.rb
63
+ - lib/dalli/protocol/value_compressor.rb
68
64
  - lib/dalli/ring.rb
69
65
  - lib/dalli/server.rb
70
66
  - lib/dalli/socket.rb
71
67
  - lib/dalli/version.rb
72
- - lib/dalli.rb
73
68
  - lib/rack/session/dalli.rb
74
- - LICENSE
75
- - README.md
76
- - History.md
77
- - Rakefile
78
- - Gemfile
79
- - dalli.gemspec
80
- - Performance.md
81
- - test/benchmark_test.rb
82
- - test/helper.rb
83
- - test/memcached_mock.rb
84
- - test/sasldb
85
- - test/test_active_support.rb
86
- - test/test_cas_client.rb
87
- - test/test_compressor.rb
88
- - test/test_dalli.rb
89
- - test/test_encoding.rb
90
- - test/test_failover.rb
91
- - test/test_network.rb
92
- - test/test_rack_session.rb
93
- - test/test_ring.rb
94
- - test/test_sasl.rb
95
- - test/test_serializer.rb
96
- homepage: http://github.com/mperham/dalli
69
+ homepage: https://github.com/petergoldstein/dalli
97
70
  licenses:
98
71
  - MIT
99
72
  metadata: {}
100
- post_install_message:
101
- rdoc_options:
102
- - --charset=UTF-8
73
+ post_install_message:
74
+ rdoc_options: []
103
75
  require_paths:
104
76
  - lib
105
77
  required_ruby_version: !ruby/object:Gem::Requirement
106
78
  requirements:
107
- - - '>='
79
+ - - ">="
108
80
  - !ruby/object:Gem::Version
109
81
  version: '0'
110
82
  required_rubygems_version: !ruby/object:Gem::Requirement
111
83
  requirements:
112
- - - '>='
84
+ - - ">="
113
85
  - !ruby/object:Gem::Version
114
86
  version: '0'
115
87
  requirements: []
116
- rubyforge_project:
117
- rubygems_version: 2.0.14
118
- signing_key:
88
+ rubygems_version: 3.2.30
89
+ signing_key:
119
90
  specification_version: 4
120
91
  summary: High performance memcached client for Ruby
121
- test_files:
122
- - test/benchmark_test.rb
123
- - test/helper.rb
124
- - test/memcached_mock.rb
125
- - test/sasldb
126
- - test/test_active_support.rb
127
- - test/test_cas_client.rb
128
- - test/test_compressor.rb
129
- - test/test_dalli.rb
130
- - test/test_encoding.rb
131
- - test/test_failover.rb
132
- - test/test_network.rb
133
- - test/test_rack_session.rb
134
- - test/test_ring.rb
135
- - test/test_sasl.rb
136
- - test/test_serializer.rb
92
+ test_files: []
data/Performance.md DELETED
@@ -1,42 +0,0 @@
1
- Performance
2
- ====================
3
-
4
- Caching is all about performance, so I carefully track Dalli performance to ensure no regressions.
5
- You can optionally use kgio to give Dalli a 10-20% performance boost: `gem install kgio`.
6
-
7
- Note I've added some benchmarks over time to Dalli that the other libraries don't necessarily have.
8
-
9
- memcache-client
10
- ---------------
11
-
12
- Testing 1.8.5 with ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-darwin11.2.0]
13
-
14
- user system total real
15
- set:plain:memcache-client 1.860000 0.310000 2.170000 ( 2.188030)
16
- set:ruby:memcache-client 1.830000 0.290000 2.120000 ( 2.130212)
17
- get:plain:memcache-client 1.830000 0.340000 2.170000 ( 2.176156)
18
- get:ruby:memcache-client 1.900000 0.330000 2.230000 ( 2.235045)
19
- multiget:ruby:memcache-client 0.860000 0.120000 0.980000 ( 0.987348)
20
- missing:ruby:memcache-client 1.630000 0.320000 1.950000 ( 1.954867)
21
- mixed:ruby:memcache-client 3.690000 0.670000 4.360000 ( 4.364469)
22
-
23
-
24
- dalli
25
- -----
26
-
27
- Testing with Rails 3.2.1
28
- Using kgio socket IO
29
- Testing 2.0.0 with ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-darwin11.3.0]
30
-
31
- user system total real
32
- mixed:rails:dalli 1.580000 0.570000 2.150000 ( 3.008839)
33
- set:plain:dalli 0.730000 0.300000 1.030000 ( 1.567098)
34
- setq:plain:dalli 0.520000 0.120000 0.640000 ( 0.634402)
35
- set:ruby:dalli 0.800000 0.300000 1.100000 ( 1.640348)
36
- get:plain:dalli 0.840000 0.330000 1.170000 ( 1.668425)
37
- get:ruby:dalli 0.850000 0.330000 1.180000 ( 1.665716)
38
- multiget:ruby:dalli 0.700000 0.260000 0.960000 ( 0.965423)
39
- missing:ruby:dalli 0.720000 0.320000 1.040000 ( 1.511720)
40
- mixed:ruby:dalli 1.660000 0.640000 2.300000 ( 3.320743)
41
- mixedq:ruby:dalli 1.630000 0.510000 2.140000 ( 2.629734)
42
- incr:ruby:dalli 0.270000 0.100000 0.370000 ( 0.547618)