dalli 1.1.2 → 1.1.3

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/History.md CHANGED
@@ -1,6 +1,14 @@
1
1
  Dalli Changelog
2
2
  =====================
3
3
 
4
+ 1.1.3
5
+ =======
6
+
7
+ - Support Rails's autoloading hack for loading sessions with objects
8
+ whose classes have not be required yet, GH-129
9
+ - Support Unix sockets for connectivity. Shows a 2x performance
10
+ increase but keep in mind they only work on localhost. (dfens)
11
+
4
12
  1.1.2
5
13
  =======
6
14
 
data/README.md CHANGED
@@ -31,10 +31,27 @@ So a few notes. Dalli:
31
31
  6. has a backwards-compatibility mode for people migrating from memcache-client (see Upgrade.md).
32
32
 
33
33
 
34
+ Supported Ruby versions and implementations
35
+ ------------------------------------------------
36
+
37
+ Dalli is geared towards 1.9.2+ but known to work on
38
+
39
+ * Ruby 1.9.2
40
+ * Ruby 1.9.3
41
+ * Ruby 1.8.7
42
+ * Rubinius 2.0 Preview
43
+
44
+
34
45
  Installation and Usage
35
46
  ------------------------
36
47
 
37
- Remember, Dalli **requires** memcached 1.4+. You can check the version with `memcached -h`.
48
+ Remember, Dalli **requires** memcached 1.4+. You can check the version with `memcached -h`. Please note that memcached that Mac OS X Snow Leopard ships with is 1.2.8 and
49
+ won't work. Install 1.4.x using Homebrew with
50
+
51
+ brew install memcached
52
+
53
+
54
+ You can verify your installation using this piece of code:
38
55
 
39
56
  gem install dalli
40
57
 
@@ -84,8 +101,13 @@ Put this at the bottom of `config/environment.rb`:
84
101
 
85
102
  if defined?(PhusionPassenger)
86
103
  PhusionPassenger.on_event(:starting_worker_process) do |forked|
104
+ # Reset Rails's object cache
87
105
  # Only works with DalliStore
88
106
  Rails.cache.reset if forked
107
+
108
+ # Reset Rails's session store
109
+ # If you know a cleaner way to find the session store instance, please let me know
110
+ ObjectSpace.each_object(ActionDispatch::Session::DalliStore) { |obj| obj.reset }
89
111
  end
90
112
  end
91
113
 
@@ -33,8 +33,10 @@ module ActionDispatch
33
33
  sid ||= generate_sid
34
34
  begin
35
35
  session = @pool.get(sid) || {}
36
- rescue Dalli::DalliError
37
- Rails.logger.warn("Session::DalliStore#get: #{$!.message}")
36
+ rescue Dalli::DalliError => ex
37
+ # re-raise ArgumentError so Rails' session abstract_store.rb can autoload any missing models
38
+ raise ArgumentError, ex.message if ex.message =~ /unmarshal/
39
+ Rails.logger.warn("Session::DalliStore#get: #{ex.message}")
38
40
  session = {}
39
41
  end
40
42
  [sid, session]
@@ -5,15 +5,22 @@ module Dalli
5
5
  ##
6
6
  # Dalli::Client is the main class which developers will use to interact with
7
7
  # the memcached server. Usage:
8
- #
8
+ #
9
9
  # Dalli::Client.new(['localhost:11211:10', 'cache-2.example.com:11211:5', '192.168.0.1:22122:5'],
10
10
  # :threadsafe => true, :failover => true, :expires_in => 300)
11
- #
11
+ #
12
12
  # servers is an Array of "host:port:weight" where weight allows you to distribute cache unevenly.
13
13
  # Both weight and port are optional. If you pass in nil, Dalli will default to 'localhost:11211'.
14
14
  # Note that the <tt>MEMCACHE_SERVERS</tt> environment variable will override the servers parameter for use
15
15
  # in managed environments like Heroku.
16
16
  #
17
+ # You can also provide a Unix socket as an argument, for example:
18
+ #
19
+ # Dalli::Client.new("/tmp/memcached.sock")
20
+ #
21
+ # Initial testing shows that Unix sockets are about twice as fast as TCP sockets
22
+ # but Unix sockets only work on localhost.
23
+ #
17
24
  # Options:
18
25
  # - :failover - if a server is down, look for and store values on another server in the ring. Default: true.
19
26
  # - :threadsafe - ensure that only one thread is actively using a socket at a time. Default: true.
@@ -92,6 +92,10 @@ module Dalli
92
92
 
93
93
  private
94
94
 
95
+ def is_unix_socket?(string)
96
+ !!(/^\/(.+)$/ =~ string)
97
+ end
98
+
95
99
  def failure!
96
100
  Dalli.logger.info { "#{hostname}:#{port} failed (count: #{@fail_count})" }
97
101
 
@@ -382,7 +386,9 @@ module Dalli
382
386
  Dalli.logger.debug { "Dalli::Server#connect #{hostname}:#{port}" }
383
387
 
384
388
  begin
385
- if options[:async]
389
+ if @hostname =~ /^\//
390
+ @sock = USocket.new(hostname)
391
+ elsif options[:async]
386
392
  raise Dalli::DalliError, "EM support not enabled, as em-synchrony is not installed." if not defined?(AsyncSocket)
387
393
  @sock = AsyncSocket.open(hostname, port, :timeout => options[:socket_timeout])
388
394
  else
@@ -34,6 +34,8 @@ begin
34
34
 
35
35
  end
36
36
 
37
+
38
+
37
39
  if ::Kgio.respond_to?(:wait_readable=)
38
40
  ::Kgio.wait_readable = :kgio_wait_readable
39
41
  ::Kgio.wait_writable = :kgio_wait_writable
@@ -147,3 +149,13 @@ rescue LoadError
147
149
  puts "Could not define alternate em-synchrony socket IO" if defined?($TESTING) && $TESTING
148
150
  end
149
151
 
152
+ class Dalli::Server::USocket < UNIXSocket
153
+ def readfull(count)
154
+ value = ''
155
+ loop do
156
+ value << read(count - value.bytesize)
157
+ break if value.bytesize == count
158
+ end
159
+ value
160
+ end
161
+ end
@@ -1,3 +1,3 @@
1
1
  module Dalli
2
- VERSION = '1.1.2'
2
+ VERSION = '1.1.3'
3
3
  end
@@ -15,6 +15,10 @@ module MemcachedMock
15
15
  block.call server
16
16
  end
17
17
 
18
+ def self.tmp_socket_path
19
+ "#{Dir.pwd}/tmp.sock"
20
+ end
21
+
18
22
  module Helper
19
23
  # Forks the current process and starts a new mock Memcached server on
20
24
  # port 22122.
@@ -69,7 +73,13 @@ module MemcachedMock
69
73
  def memcached(port=19122, args='', options={})
70
74
  return unless supports_fork?
71
75
  Memcached.path ||= find_memcached
72
- cmd = "#{Memcached.path}memcached #{args} -p #{port}"
76
+
77
+ cmd = if options[:unix]
78
+ "#{Memcached.path}memcached #{args} -s #{MemcachedMock.tmp_socket_path}"
79
+ else
80
+ "#{Memcached.path}memcached #{args} -p #{port}"
81
+ end
82
+
73
83
  $started[port] ||= begin
74
84
  #puts "Starting: #{cmd}..."
75
85
  pid = IO.popen(cmd).pid
@@ -77,18 +87,22 @@ module MemcachedMock
77
87
  begin
78
88
  Process.kill("TERM", pid)
79
89
  Process.wait(pid)
90
+ File.delete(MemcachedMock.tmp_socket_path) if options[:unix]
80
91
  rescue Errno::ECHILD, Errno::ESRCH
81
92
  end
82
93
  end
83
94
  sleep 0.1
84
95
  pid
85
96
  end
86
-
87
- yield Dalli::Client.new(["localhost:#{port}", "127.0.0.1:#{port}"], options)
97
+ if options[:unix]
98
+ yield Dalli::Client.new(MemcachedMock.tmp_socket_path)
99
+ else
100
+ yield Dalli::Client.new(["localhost:#{port}", "127.0.0.1:#{port}"], options)
101
+ end
88
102
  end
89
103
 
90
104
  def supports_fork?
91
- RUBY_ENGINE != 'jruby'
105
+ !defined?(RUBY_ENGINE) || RUBY_ENGINE != 'jruby'
92
106
  end
93
107
 
94
108
  def memcached_kill(port)
@@ -26,6 +26,60 @@ class TestDalli < Test::Unit::TestCase
26
26
  assert_equal s2, s3
27
27
  end
28
28
 
29
+ context 'using unix sockets' do
30
+ should 'pass smoke test' do
31
+ memcached(nil,'',{:unix => true}) do |dc|
32
+ # get/set
33
+ dc.flush
34
+ assert_nil dc.get(:a)
35
+ assert dc.set(:a,1)
36
+ assert_equal 1, dc.get(:a)
37
+
38
+ # replace
39
+ dc.set(:a,1)
40
+ dc.replace(:a,2)
41
+ assert_equal 2, dc.get(:a)
42
+
43
+ # delete
44
+ dc.delete(:a)
45
+ assert_nil dc.get(:a)
46
+
47
+ # fetch
48
+ executed, expected = false, 1
49
+
50
+ value = dc.fetch(:fetched) do
51
+ executed = true
52
+ expected
53
+ end
54
+
55
+ assert executed
56
+ assert_equal expected, value
57
+
58
+ executed = false
59
+ value = dc.fetch(:fetched) do
60
+ executed = true
61
+ expected
62
+ end
63
+
64
+ assert !executed
65
+ assert_equal expected, value
66
+
67
+ # cas
68
+ dc.set(:a,1)
69
+ 3.times { dc.cas(:a){|a| a+=1} }
70
+ assert_equal 4, dc.get(:a)
71
+
72
+ # get_multi
73
+ resp = dc.get_multi(%w(b c d))
74
+ assert_equal({}, resp)
75
+ dc.set("b",1)
76
+ dc.set("c",11)
77
+ resp = dc.get_multi(%w(b c d))
78
+ assert_equal({"b" => 1, "c" => 11}, resp)
79
+ end
80
+ end
81
+ end
82
+
29
83
  context 'using a live server' do
30
84
 
31
85
  should "support get/set" do
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
  require 'memcached_mock'
3
- if RUBY_ENGINE != 'jruby'
3
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE != 'jruby'
4
4
  begin
5
5
  require 'em-spec/test'
6
6
 
metadata CHANGED
@@ -1,71 +1,66 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: dalli
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.3
4
5
  prerelease:
5
- version: 1.1.2
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Mike Perham
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-09-06 00:00:00 -07:00
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
12
+ date: 2011-10-26 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
17
15
  name: shoulda
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &2152632040 !ruby/object:Gem::Requirement
20
17
  none: false
21
- requirements:
22
- - - ">="
23
- - !ruby/object:Gem::Version
24
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
25
22
  type: :development
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
28
- name: mocha
29
23
  prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *2152632040
25
+ - !ruby/object:Gem::Dependency
26
+ name: mocha
27
+ requirement: &2152630860 !ruby/object:Gem::Requirement
31
28
  none: false
32
- requirements:
33
- - - ">="
34
- - !ruby/object:Gem::Version
35
- version: "0"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
36
33
  type: :development
37
- version_requirements: *id002
38
- - !ruby/object:Gem::Dependency
39
- name: rails
40
34
  prerelease: false
41
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *2152630860
36
+ - !ruby/object:Gem::Dependency
37
+ name: rails
38
+ requirement: &2152629740 !ruby/object:Gem::Requirement
42
39
  none: false
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
46
43
  version: 3.0.0
47
44
  type: :development
48
- version_requirements: *id003
49
- - !ruby/object:Gem::Dependency
50
- name: memcache-client
51
45
  prerelease: false
52
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *2152629740
47
+ - !ruby/object:Gem::Dependency
48
+ name: memcache-client
49
+ requirement: &2152628780 !ruby/object:Gem::Requirement
53
50
  none: false
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
57
54
  version: 1.8.5
58
55
  type: :development
59
- version_requirements: *id004
56
+ prerelease: false
57
+ version_requirements: *2152628780
60
58
  description: High performance memcached client for Ruby
61
59
  email: mperham@gmail.com
62
60
  executables: []
63
-
64
61
  extensions: []
65
-
66
62
  extra_rdoc_files: []
67
-
68
- files:
63
+ files:
69
64
  - lib/action_dispatch/middleware/session/dalli_store.rb
70
65
  - lib/active_support/cache/dalli_store.rb
71
66
  - lib/active_support/cache/dalli_store23.rb
@@ -100,35 +95,32 @@ files:
100
95
  - test/test_sasl.rb
101
96
  - test/test_session_store.rb
102
97
  - test/test_synchrony.rb
103
- has_rdoc: true
104
98
  homepage: http://github.com/mperham/dalli
105
99
  licenses: []
106
-
107
100
  post_install_message:
108
- rdoc_options:
101
+ rdoc_options:
109
102
  - --charset=UTF-8
110
- require_paths:
103
+ require_paths:
111
104
  - lib
112
- required_ruby_version: !ruby/object:Gem::Requirement
105
+ required_ruby_version: !ruby/object:Gem::Requirement
113
106
  none: false
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: "0"
118
- required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
112
  none: false
120
- requirements:
121
- - - ">="
122
- - !ruby/object:Gem::Version
123
- version: "0"
113
+ requirements:
114
+ - - ! '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
124
117
  requirements: []
125
-
126
118
  rubyforge_project:
127
- rubygems_version: 1.5.2
119
+ rubygems_version: 1.8.10
128
120
  signing_key:
129
121
  specification_version: 3
130
122
  summary: High performance memcached client for Ruby
131
- test_files:
123
+ test_files:
132
124
  - test/abstract_unit.rb
133
125
  - test/benchmark_test.rb
134
126
  - test/helper.rb