cache 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -2,12 +2,40 @@
2
2
 
3
3
  A unified cache handling interface, inspired (but simpler than) Perl's Cache::Cache[http://cpan.uwinnipeg.ca/module/Cache::Cache] and CHI[http://cpan.uwinnipeg.ca/module/CHI].
4
4
 
5
+ Takes care of exceptions like Memcached::NotFound and also forking/threading.
6
+
7
+ == Example
8
+
9
+ require 'memcached' # a really fast memcached client gem
10
+ require 'client' # this gem, which provides a standard interface
11
+ raw_client = Memcached.new '127.0.0.1:11211'
12
+ cache = Cache.new raw_client
13
+
14
+ or
15
+
16
+ require 'redis' # the redis key-value store
17
+ require 'client' # this gem, which provides a standard interface
18
+ raw_client = Redis.new
19
+ cache = Cache.new raw_client
20
+
21
+ or
22
+
23
+ require 'dalli' # the dalli memcached client used by heroku
24
+ require 'client' # this gem, which provides a standard interface
25
+ raw_client = Dalli::Client.new
26
+ cache = Cache.new raw_client
27
+
28
+ Maybe this will even work:
29
+
30
+ # Piggyback off the default rails cache
31
+ cache = Cache.new Rails.cache
32
+
5
33
  == Methods
6
34
 
7
- * get
8
- * set
9
- * delete
10
- * flush
35
+ cache.get 'hello'
36
+ cache.set 'hello', 'world'
37
+ cache.delete 'hello'
38
+ cache.flush
11
39
 
12
40
  == Supported clients
13
41
 
@@ -21,29 +49,24 @@ Supported Redis clients:
21
49
 
22
50
  * redis[https://github.com/ezmobius/redis-rb]
23
51
 
24
- == Configuration
25
-
26
- You set your preferred cache client:
27
-
28
- Cache.config.client = Memcached.new '127.0.0.1:11211'
29
-
30
- or
31
-
32
- Cache.config.client = Redis.new
52
+ == TTL
33
53
 
34
- or this might even work...
54
+ 0 means don't expire.
35
55
 
36
- Cache.config.client = Rails.cache
56
+ == Forking/threading
37
57
 
38
- == TTL
58
+ When you use a Cache object to wrap Memcached or Redis, you don't have to worry about forking or threading.
39
59
 
40
- 0 means don't expire.
60
+ For example, you don't have to set up unicorn or PhusionPassenger's <tt>after_fork</tt>.
41
61
 
42
62
  == Rationale
43
63
 
64
+ I wanted a common interface to a bunch of great Ruby cache clients so I can develop gems (lock_method, cache_method) that accept any of them.
65
+
44
66
  * I am so tired of rescuing from Memcached::NotFound
45
67
  * I am so tired of forgetting whether it's :expires_in or :ttl
46
68
  * I don't know why we ever started using read/write instead of get/set.
69
+ * I don't like how you have to manually handle after_fork for Redis, Memcached, etc.
47
70
 
48
71
  == Currently unsupported
49
72
 
data/lib/cache.rb CHANGED
@@ -1,42 +1,63 @@
1
1
  require 'cache/version'
2
- module Cache
2
+ class Cache
3
3
  autoload :Config, 'cache/config'
4
4
  autoload :Storage, 'cache/storage'
5
-
6
- def self.config #:nodoc:
7
- Config.instance
5
+
6
+ # Create a new Cache object by passing it a client of your choice.
7
+ #
8
+ # Supported memcached clients:
9
+ # * memcached[https://github.com/fauna/memcached] (either a Memcached or a Memcached::Rails)
10
+ # * dalli[https://github.com/mperham/dalli] (either a Dalli::Client or an ActiveSupport::Cache::DalliStore)
11
+ # * memcache-client[https://github.com/mperham/memcache-client] (MemCache, the one commonly used by Rails)
12
+ #
13
+ # Supported Redis clients:
14
+ # * redis[https://github.com/ezmobius/redis-rb]
15
+ #
16
+ # Example:
17
+ # raw_client = Memcached.new('127.0.0.1:11211')
18
+ # cache = Cache.new raw_client
19
+ def initialize(client)
20
+ config.client = client
21
+ end
22
+
23
+ def config #:nodoc:
24
+ @config ||= Config.new self
25
+ end
26
+
27
+ def storage #:nodoc:
28
+ @storage ||= Storage.new self
8
29
  end
9
30
 
10
31
  # Get a value.
11
32
  #
12
33
  # Example:
13
- # Cache.get 'hello'
14
- def self.get(k)
15
- Storage.instance.get k
34
+ # cache.get 'hello'
35
+ def get(k)
36
+ storage.get k
16
37
  end
17
38
 
18
39
  # Store a value. Note that this will Marshal it.
19
40
  #
20
41
  # Example:
21
- # Cache.set 'hello', 'world'
22
- # Cache.set 'hello', 'world', 80 # seconds til it expires
23
- def self.set(k, v, ttl = nil)
24
- Storage.instance.set k, v, ttl
42
+ # cache.set 'hello', 'world'
43
+ # cache.set 'hello', 'world', 80 # seconds til it expires
44
+ def set(k, v, ttl = nil)
45
+ storage.set k, v, ttl
25
46
  end
26
47
 
27
48
  # Delete a value.
28
49
  #
29
50
  # Example:
30
- # Cache.delete 'hello'
31
- def self.delete(k)
32
- Storage.instance.delete k
51
+ # cache.delete 'hello'
52
+ def delete(k)
53
+ storage.delete k
33
54
  end
34
55
 
35
56
  # Flush the cache.
36
57
  #
37
58
  # Example:
38
- # Cache.flush
39
- def self.flush
40
- Storage.instance.flush
59
+ # cache.flush
60
+ def flush
61
+ storage.flush
41
62
  end
42
63
  end
data/lib/cache/config.rb CHANGED
@@ -1,39 +1,34 @@
1
- require 'singleton'
2
- module Cache
3
- # Here's where you set config options.
1
+ class Cache
2
+ # Here's where config options are kept.
4
3
  #
5
4
  # Example:
6
- # Cache.config.client = Memcached.new '127.0.0.1:11211'
7
- # Cache.config.default_ttl = 120 # seconds
8
- #
9
- # You'd probably put this in your Rails config/initializers, for example.
5
+ # cache.config.default_ttl = 120 # seconds
10
6
  class Config
11
- include ::Singleton
7
+
8
+ attr_reader :parent
9
+
10
+ def initialize(parent) #:nodoc:
11
+ @parent = parent
12
+ end
12
13
 
13
14
  # The cache client to use.
14
15
  #
15
- # Supported memcached clients:
16
- # * memcached[https://github.com/fauna/memcached] (either a Memcached or a Memcached::Rails)
17
- # * dalli[https://github.com/mperham/dalli] (either a Dalli::Client or an ActiveSupport::Cache::DalliStore)
18
- # * memcache-client[https://github.com/mperham/memcache-client] (MemCache, the one commonly used by Rails)
19
- #
20
- # Supported Redis clients:
21
- # * redis[https://github.com/ezmobius/redis-rb]
16
+ # Note that you normally just set this when you initialize a Cache object.
22
17
  #
23
18
  # Example:
24
- # Cache.config.storage = Memcached.new '127.0.0.1:11211'
25
- def client=(client)
19
+ # cache.config.client = Memcached.new '127.0.0.1:11211'
20
+ def client=(client) #:nodoc:
26
21
  @client = client
27
22
  end
28
23
 
29
24
  def client #:nodoc:
30
- @client
25
+ @client || raise("You didn't select a cache client")
31
26
  end
32
27
 
33
28
  # TTL for method caches. Defaults to 60 seconds.
34
29
  #
35
30
  # Example:
36
- # Cache.config.default_ttl = 120 # seconds
31
+ # cache.config.default_ttl = 120 # seconds
37
32
  def default_ttl=(seconds)
38
33
  @default_ttl = seconds
39
34
  end
data/lib/cache/storage.rb CHANGED
@@ -1,8 +1,14 @@
1
- require 'singleton'
2
- module Cache
1
+ class Cache
3
2
  class Storage #:nodoc: all
4
- include ::Singleton
5
-
3
+
4
+ attr_reader :parent
5
+
6
+ def initialize(parent)
7
+ @parent = parent
8
+ @pid = ::Process.pid
9
+ @thread_object_id = ::Thread.current.object_id
10
+ end
11
+
6
12
  def get(k)
7
13
  if defined?(::Memcached) and bare_client.is_a?(::Memcached)
8
14
  begin; bare_client.get(k); rescue ::Memcached::NotFound; nil; end
@@ -20,7 +26,7 @@ module Cache
20
26
  end
21
27
 
22
28
  def set(k, v, ttl)
23
- ttl ||= Config.instance.default_ttl
29
+ ttl ||= parent.config.default_ttl
24
30
  if defined?(::Redis) and bare_client.is_a?(::Redis)
25
31
  if ttl == 0
26
32
  bare_client.set k, ::Marshal.dump(v)
@@ -56,35 +62,37 @@ module Cache
56
62
  bare_client.send %w{ flush flushdb flush_all clear }.detect { |flush_cmd| bare_client.respond_to? flush_cmd }
57
63
  end
58
64
 
59
- def bare_client
60
- if @pid == ::Process.pid
61
- fork_detected = false
62
- else
63
- fork_detected = true
64
- ::Thread.current[:cache_storage_bare_client] = nil
65
+ private
66
+
67
+ def fork_detected?
68
+ if @pid != ::Process.pid
65
69
  @pid = ::Process.pid
66
70
  end
67
- ::Thread.current[:cache_storage_bare_client] ||= fresh_bare_client(fork_detected)
68
71
  end
69
72
 
70
- def fresh_bare_client(fork_detected)
71
- if defined?(::Dalli) and Config.instance.client.is_a?(::Dalli::Client)
72
- Config.instance.client.close if fork_detected
73
- Config.instance.client
74
- elsif defined?(::ActiveSupport::Cache::DalliStore) and Config.instance.client.is_a?(::ActiveSupport::Cache::DalliStore)
75
- Config.instance.client.reset if fork_detected
76
- Config.instance.client
77
- elsif defined?(::Memcached) and (Config.instance.client.is_a?(::Memcached) or Config.instance.client.is_a?(::Memcached::Rails))
78
- Config.instance.client.clone
79
- elsif defined?(::Redis) and Config.instance.client.is_a?(::Redis)
80
- Config.instance.client.client.connect if fork_detected
81
- Config.instance.client
82
- elsif defined?(::MemCache) and Config.instance.client.is_a?(::MemCache)
83
- Config.instance.client.reset if fork_detected
84
- Config.instance.client
73
+ def new_thread_detected?
74
+ if @thread_object_id != ::Thread.current.object_id
75
+ @thread_object_id = ::Thread.current.object_id
76
+ end
77
+ end
78
+
79
+ def bare_client
80
+ fork_detected = fork_detected?
81
+ new_thread_detected = new_thread_detected?
82
+ if defined?(::Dalli) and parent.config.client.is_a?(::Dalli::Client)
83
+ parent.config.client.close if fork_detected
84
+ elsif defined?(::ActiveSupport::Cache::DalliStore) and parent.config.client.is_a?(::ActiveSupport::Cache::DalliStore)
85
+ parent.config.client.reset if fork_detected
86
+ elsif defined?(::Memcached) and (parent.config.client.is_a?(::Memcached) or parent.config.client.is_a?(::Memcached::Rails))
87
+ parent.config.client = parent.config.client.clone if fork_detected or new_thread_detected
88
+ elsif defined?(::Redis) and parent.config.client.is_a?(::Redis)
89
+ parent.config.client.client.connect if fork_detected
90
+ elsif defined?(::MemCache) and parent.config.client.is_a?(::MemCache)
91
+ parent.config.client.reset if fork_detected
85
92
  else
86
- raise "Don't know how to thread/fork #{Config.instance.client.inspect}"
93
+ raise "Don't know how to thread/fork #{parent.config.client.inspect}"
87
94
  end
95
+ parent.config.client
88
96
  end
89
97
  end
90
98
  end
data/lib/cache/version.rb CHANGED
@@ -1,3 +1,3 @@
1
- module Cache
2
- VERSION = "0.0.1"
1
+ class Cache
2
+ VERSION = "0.0.2"
3
3
  end
data/test/helper.rb CHANGED
@@ -10,4 +10,8 @@ require 'cache'
10
10
  require 'shared_tests'
11
11
 
12
12
  class Test::Unit::TestCase
13
+ def setup
14
+ @cache = Cache.new @client
15
+ @cache.flush
16
+ end
13
17
  end
data/test/shared_tests.rb CHANGED
@@ -1,41 +1,41 @@
1
1
  module SharedTests
2
2
  def test_get
3
- assert_equal nil, Cache.get('hello')
4
- Cache.set 'hello', 'world'
5
- assert_equal 'world', Cache.get('hello')
3
+ assert_equal nil, @cache.get('hello')
4
+ @cache.set 'hello', 'world'
5
+ assert_equal 'world', @cache.get('hello')
6
6
  end
7
7
 
8
8
  def test_set
9
9
  assert_nothing_raised do
10
- Cache.set 'hello', 'world'
10
+ @cache.set 'hello', 'world'
11
11
  end
12
12
  end
13
13
 
14
14
  def test_set_with_ttl
15
- Cache.set 'hello', 'world', 1
16
- assert_equal 'world', Cache.get('hello')
15
+ @cache.set 'hello', 'world', 1
16
+ assert_equal 'world', @cache.get('hello')
17
17
  sleep 2
18
- assert_equal nil, Cache.get('hello')
18
+ assert_equal nil, @cache.get('hello')
19
19
  end
20
20
 
21
21
  def test_set_with_zero_ttl_meaning_eternal
22
- Cache.set 'hello', 'world', 0
23
- assert_equal 'world', Cache.get('hello')
22
+ @cache.set 'hello', 'world', 0
23
+ assert_equal 'world', @cache.get('hello')
24
24
  sleep 1
25
- assert_equal 'world', Cache.get('hello')
25
+ assert_equal 'world', @cache.get('hello')
26
26
  end
27
27
 
28
28
  def test_delete
29
- Cache.set 'hello', 'world'
30
- assert_equal 'world', Cache.get('hello')
31
- Cache.delete 'hello'
32
- assert_equal nil, Cache.get('hello')
29
+ @cache.set 'hello', 'world'
30
+ assert_equal 'world', @cache.get('hello')
31
+ @cache.delete 'hello'
32
+ assert_equal nil, @cache.get('hello')
33
33
  end
34
34
 
35
35
  def test_flush
36
- Cache.set 'hello', 'world'
37
- assert_equal 'world', Cache.get('hello')
38
- Cache.flush
39
- assert_equal nil, Cache.get('hello')
36
+ @cache.set 'hello', 'world'
37
+ assert_equal 'world', @cache.get('hello')
38
+ @cache.flush
39
+ assert_equal nil, @cache.get('hello')
40
40
  end
41
41
  end
@@ -4,31 +4,29 @@ require 'dalli'
4
4
 
5
5
  class TestDalliStorage < Test::Unit::TestCase
6
6
  def setup
7
+ @client = Dalli::Client.new ['localhost:11211']
7
8
  super
8
- client = Dalli::Client.new ['localhost:11211']
9
- client.flush
10
- Cache.config.client = client
11
9
  end
12
10
 
13
11
  include SharedTests
14
12
 
15
13
  def get_ring_object_id
16
- Cache.config.client.instance_variable_get(:@ring).object_id
14
+ @cache.config.client.instance_variable_get(:@ring).object_id
17
15
  end
18
16
 
19
17
  def test_treats_as_thread_safe
20
18
  # make sure ring is initialized
21
- Cache.get 'hi'
19
+ @cache.get 'hi'
22
20
 
23
21
  # get the main thread's ring
24
22
  main_thread_ring_id = get_ring_object_id
25
23
 
26
24
  # sanity check that it's not changing every time
27
- Cache.get 'hi'
25
+ @cache.get 'hi'
28
26
  assert_equal main_thread_ring_id, get_ring_object_id
29
27
 
30
28
  # create a new thread and get its ring
31
- new_thread_ring_id = Thread.new { Cache.get 'hi'; get_ring_object_id }.value
29
+ new_thread_ring_id = Thread.new { @cache.get 'hi'; get_ring_object_id }.value
32
30
 
33
31
  # make sure the ring was reinitialized
34
32
  assert_equal main_thread_ring_id, new_thread_ring_id
@@ -36,18 +34,18 @@ class TestDalliStorage < Test::Unit::TestCase
36
34
 
37
35
  def test_treats_as_not_fork_safe
38
36
  # make sure ring is initialized
39
- Cache.get 'hi'
37
+ @cache.get 'hi'
40
38
 
41
39
  # get the main thread's ring
42
40
  parent_process_ring_id = get_ring_object_id
43
41
 
44
42
  # sanity check that it's not changing every time
45
- Cache.get 'hi'
43
+ @cache.get 'hi'
46
44
  assert_equal parent_process_ring_id, get_ring_object_id
47
45
 
48
46
  # fork a new process
49
47
  pid = Kernel.fork do
50
- Cache.get 'hi'
48
+ @cache.get 'hi'
51
49
  raise "Didn't split!" if parent_process_ring_id == get_ring_object_id
52
50
  end
53
51
  Process.wait pid
@@ -6,32 +6,30 @@ require 'active_support/cache/dalli_store'
6
6
 
7
7
  class TestDalliStoreStorage < Test::Unit::TestCase
8
8
  def setup
9
+ @client = ActiveSupport::Cache::DalliStore.new ['localhost:11211']
9
10
  super
10
- client = ActiveSupport::Cache::DalliStore.new ['localhost:11211']
11
- client.clear
12
- Cache.config.client = client
13
11
  end
14
12
 
15
13
  include SharedTests
16
14
 
17
15
  def get_ring_object_id
18
- hidden_dalli_client = Cache.config.client.instance_variable_get :@data
16
+ hidden_dalli_client = @cache.config.client.instance_variable_get :@data
19
17
  hidden_dalli_client.instance_variable_get(:@ring).object_id
20
18
  end
21
19
 
22
20
  def test_treats_as_thread_safe
23
21
  # make sure ring is initialized
24
- Cache.get 'hi'
22
+ @cache.get 'hi'
25
23
 
26
24
  # get the main thread's ring
27
25
  main_thread_ring_id = get_ring_object_id
28
26
 
29
27
  # sanity check that it's not changing every time
30
- Cache.get 'hi'
28
+ @cache.get 'hi'
31
29
  assert_equal main_thread_ring_id, get_ring_object_id
32
30
 
33
31
  # create a new thread and get its ring
34
- new_thread_ring_id = Thread.new { Cache.get 'hi'; get_ring_object_id }.value
32
+ new_thread_ring_id = Thread.new { @cache.get 'hi'; get_ring_object_id }.value
35
33
 
36
34
  # make sure the ring was reinitialized
37
35
  assert_equal main_thread_ring_id, new_thread_ring_id
@@ -39,18 +37,18 @@ class TestDalliStoreStorage < Test::Unit::TestCase
39
37
 
40
38
  def test_treats_as_not_fork_safe
41
39
  # make sure ring is initialized
42
- Cache.get 'hi'
40
+ @cache.get 'hi'
43
41
 
44
42
  # get the main thread's ring
45
43
  parent_process_ring_id = get_ring_object_id
46
44
 
47
45
  # sanity check that it's not changing every time
48
- Cache.get 'hi'
46
+ @cache.get 'hi'
49
47
  assert_equal parent_process_ring_id, get_ring_object_id
50
48
 
51
49
  # fork a new process
52
50
  pid = Kernel.fork do
53
- Cache.get 'hi'
51
+ @cache.get 'hi'
54
52
  raise "Didn't split!" if parent_process_ring_id == get_ring_object_id
55
53
  end
56
54
  Process.wait pid
@@ -5,31 +5,29 @@ require 'memcache'
5
5
 
6
6
  class TestMemcacheStorage < Test::Unit::TestCase
7
7
  def setup
8
+ @client = MemCache.new ['localhost:11211']
8
9
  super
9
- client = MemCache.new ['localhost:11211']
10
- client.flush_all
11
- Cache.config.client = client
12
10
  end
13
11
 
14
12
  include SharedTests
15
13
 
16
14
  def get_server_status_ids
17
- Cache.config.client.instance_variable_get(:@servers).map { |s| s.status.object_id }
15
+ @cache.config.client.instance_variable_get(:@servers).map { |s| s.status.object_id }
18
16
  end
19
17
 
20
18
  def test_treats_as_thread_safe
21
19
  # make sure servers are connected
22
- Cache.get 'hi'
20
+ @cache.get 'hi'
23
21
 
24
22
  # get the object ids
25
23
  main_thread_server_status_ids = get_server_status_ids
26
24
 
27
25
  # sanity check that it's not changing every time
28
- Cache.get 'hi'
26
+ @cache.get 'hi'
29
27
  assert_equal main_thread_server_status_ids, get_server_status_ids
30
28
 
31
29
  # create a new thread and get its server ids
32
- new_thread_server_status_ids = Thread.new { Cache.get 'hi'; get_server_status_ids }.value
30
+ new_thread_server_status_ids = Thread.new { @cache.get 'hi'; get_server_status_ids }.value
33
31
 
34
32
  # make sure the server ids was reinitialized
35
33
  assert_equal main_thread_server_status_ids, new_thread_server_status_ids
@@ -37,18 +35,18 @@ class TestMemcacheStorage < Test::Unit::TestCase
37
35
 
38
36
  def test_treats_as_not_fork_safe
39
37
  # make sure server ids is initialized
40
- Cache.get 'hi'
38
+ @cache.get 'hi'
41
39
 
42
40
  # get the main thread's server ids
43
41
  parent_process_server_status_ids = get_server_status_ids
44
42
 
45
43
  # sanity check that it's not changing every time
46
- Cache.get 'hi'
44
+ @cache.get 'hi'
47
45
  assert_equal parent_process_server_status_ids, get_server_status_ids
48
46
 
49
47
  # fork a new process
50
48
  pid = Kernel.fork do
51
- Cache.get 'hi'
49
+ @cache.get 'hi'
52
50
  raise "Didn't split!" if parent_process_server_status_ids == get_server_status_ids
53
51
  end
54
52
  Process.wait pid
@@ -4,31 +4,29 @@ require 'memcached'
4
4
 
5
5
  class TestMemcachedRailsStorage < Test::Unit::TestCase
6
6
  def setup
7
+ @client = Memcached::Rails.new 'localhost:11211'
7
8
  super
8
- client = Memcached::Rails.new 'localhost:11211'
9
- client.flush
10
- Cache.config.client = client
11
9
  end
12
10
 
13
11
  include SharedTests
14
12
 
15
13
  def get_bare_client_id
16
- Cache::Storage.instance.bare_client.object_id
14
+ @cache.storage.send(:bare_client).object_id
17
15
  end
18
16
 
19
17
  def test_treats_as_not_thread_safe
20
18
  # make sure bare client is initialized
21
- Cache.get 'hi'
19
+ @cache.get 'hi'
22
20
 
23
21
  # get the main thread's bare client
24
22
  main_thread_bare_client_id = get_bare_client_id
25
23
 
26
24
  # sanity check that it's not changing every time
27
- Cache.get 'hi'
25
+ @cache.get 'hi'
28
26
  assert_equal main_thread_bare_client_id, get_bare_client_id
29
27
 
30
28
  # create a new thread and get its bare client
31
- new_thread_bare_client_id = Thread.new { Cache.get 'hi'; get_bare_client_id }.value
29
+ new_thread_bare_client_id = Thread.new { @cache.get 'hi'; get_bare_client_id }.value
32
30
 
33
31
  # make sure the bare client was reinitialized
34
32
  assert(main_thread_bare_client_id != new_thread_bare_client_id)
@@ -36,18 +34,18 @@ class TestMemcachedRailsStorage < Test::Unit::TestCase
36
34
 
37
35
  def test_treats_as_not_fork_safe
38
36
  # make sure bare client is initialized
39
- Cache.get 'hi'
37
+ @cache.get 'hi'
40
38
 
41
39
  # get the main process's bare client
42
40
  parent_process_bare_client_id = get_bare_client_id
43
41
 
44
42
  # sanity check that it's not changing every time
45
- Cache.get 'hi'
43
+ @cache.get 'hi'
46
44
  assert_equal parent_process_bare_client_id, get_bare_client_id
47
45
 
48
46
  # fork a new process
49
47
  pid = Kernel.fork do
50
- Cache.get 'hi'
48
+ @cache.get 'hi'
51
49
  raise "Didn't split!" if parent_process_bare_client_id == get_bare_client_id
52
50
  end
53
51
  Process.wait pid
@@ -4,31 +4,29 @@ require 'memcached'
4
4
 
5
5
  class TestMemcachedStorage < Test::Unit::TestCase
6
6
  def setup
7
+ @client = Memcached.new 'localhost:11211'
7
8
  super
8
- client = Memcached.new 'localhost:11211'
9
- client.flush
10
- Cache.config.client = client
11
9
  end
12
10
 
13
11
  include SharedTests
14
12
 
15
13
  def get_bare_client_id
16
- Cache::Storage.instance.bare_client.object_id
14
+ @cache.storage.send(:bare_client).object_id
17
15
  end
18
16
 
19
17
  def test_treats_as_not_thread_safe
20
18
  # make sure bare client is initialized
21
- Cache.get 'hi'
19
+ @cache.get 'hi'
22
20
 
23
21
  # get the main thread's bare client
24
22
  main_thread_bare_client_id = get_bare_client_id
25
23
 
26
24
  # sanity check that it's not changing every time
27
- Cache.get 'hi'
25
+ @cache.get 'hi'
28
26
  assert_equal main_thread_bare_client_id, get_bare_client_id
29
27
 
30
28
  # create a new thread and get its bare client
31
- new_thread_bare_client_id = Thread.new { Cache.get 'hi'; get_bare_client_id }.value
29
+ new_thread_bare_client_id = Thread.new { @cache.get 'hi'; get_bare_client_id }.value
32
30
 
33
31
  # make sure the bare client was reinitialized
34
32
  assert(main_thread_bare_client_id != new_thread_bare_client_id)
@@ -36,18 +34,18 @@ class TestMemcachedStorage < Test::Unit::TestCase
36
34
 
37
35
  def test_treats_as_not_fork_safe
38
36
  # make sure bare client is initialized
39
- Cache.get 'hi'
37
+ @cache.get 'hi'
40
38
 
41
39
  # get the main process's bare client
42
40
  parent_process_bare_client_id = get_bare_client_id
43
41
 
44
42
  # sanity check that it's not changing every time
45
- Cache.get 'hi'
43
+ @cache.get 'hi'
46
44
  assert_equal parent_process_bare_client_id, get_bare_client_id
47
45
 
48
46
  # fork a new process
49
47
  pid = Kernel.fork do
50
- Cache.get 'hi'
48
+ @cache.get 'hi'
51
49
  raise "Didn't split!" if parent_process_bare_client_id == get_bare_client_id
52
50
  end
53
51
  Process.wait pid
@@ -6,18 +6,16 @@ if ENV['REDIS_URL']
6
6
 
7
7
  class TestRedisStorage < Test::Unit::TestCase
8
8
  def setup
9
- super
10
9
  uri = URI.parse(ENV["REDIS_URL"])
11
- client = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
12
- client.flushdb
13
- Cache.config.client = client
10
+ @client = Redis.new(:host => uri.host, :port => uri.port, :password => uri.password)
11
+ super
14
12
  end
15
13
 
16
14
  include SharedTests
17
15
 
18
16
  # client DOT client
19
17
  def get_redis_client_connection_socket_id
20
- connection = Cache.config.client.client.instance_variable_get :@connection
18
+ connection = @cache.config.client.client.instance_variable_get :@connection
21
19
  sock = connection.instance_variable_get(:@sock)
22
20
  # $stderr.puts sock.inspect
23
21
  sock.object_id
@@ -25,17 +23,17 @@ if ENV['REDIS_URL']
25
23
 
26
24
  def test_treats_as_thread_safe
27
25
  # make sure ring is initialized
28
- Cache.get 'hi'
26
+ @cache.get 'hi'
29
27
 
30
28
  # get the main thread's ring
31
29
  main_thread_redis_client_connection_socket_id = get_redis_client_connection_socket_id
32
30
 
33
31
  # sanity check that it's not changing every time
34
- Cache.get 'hi'
32
+ @cache.get 'hi'
35
33
  assert_equal main_thread_redis_client_connection_socket_id, get_redis_client_connection_socket_id
36
34
 
37
35
  # create a new thread and get its ring
38
- new_thread_redis_client_connection_socket_id = Thread.new { Cache.get 'hi'; get_redis_client_connection_socket_id }.value
36
+ new_thread_redis_client_connection_socket_id = Thread.new { @cache.get 'hi'; get_redis_client_connection_socket_id }.value
39
37
 
40
38
  # make sure the ring was reinitialized
41
39
  assert_equal main_thread_redis_client_connection_socket_id, new_thread_redis_client_connection_socket_id
@@ -43,18 +41,18 @@ if ENV['REDIS_URL']
43
41
 
44
42
  def test_treats_as_not_fork_safe
45
43
  # make sure ring is initialized
46
- Cache.get 'hi'
44
+ @cache.get 'hi'
47
45
 
48
46
  # get the main thread's ring
49
47
  parent_process_redis_client_connection_socket_id = get_redis_client_connection_socket_id
50
48
 
51
49
  # sanity check that it's not changing every time
52
- Cache.get 'hi'
50
+ @cache.get 'hi'
53
51
  assert_equal parent_process_redis_client_connection_socket_id, get_redis_client_connection_socket_id
54
52
 
55
53
  # fork a new process
56
54
  pid = Kernel.fork do
57
- Cache.get 'hi'
55
+ @cache.get 'hi'
58
56
  raise "Didn't split!" if parent_process_redis_client_connection_socket_id == get_redis_client_connection_socket_id
59
57
  end
60
58
  Process.wait pid
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cache
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Seamus Abshere