ninjudd-memcache 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/lib/memcache.rb +31 -785
- data/lib/memcache/local_server.rb +12 -12
- data/lib/memcache/pg_server.rb +5 -1
- data/memcache.gemspec +66 -0
- data/test/memcache_pg_server_test.rb +1 -1
- data/test/memcache_test.rb +3 -3
- data/test/test_helper.rb +2 -0
- metadata +3 -11
- data/lib/memcache_extended.rb +0 -120
- data/lib/memcache_mock.rb +0 -137
- data/lib/memcache_util.rb +0 -90
- data/test/test_mem_cache.rb +0 -739
- data/test/test_memcache_extended.rb +0 -44
- data/test/test_memcache_mock.rb +0 -94
@@ -50,28 +50,28 @@ class Memcache
|
|
50
50
|
incr(key, -amount)
|
51
51
|
end
|
52
52
|
|
53
|
-
def delete(key
|
54
|
-
|
55
|
-
old_expiry = @expiry[key.to_s] || Time.now + expiry
|
56
|
-
@expiry[key.to_s] = [old_expiry, expiry].min
|
57
|
-
else
|
58
|
-
@data.delete(key.to_s)
|
59
|
-
end
|
53
|
+
def delete(key)
|
54
|
+
@data.delete(key.to_s)
|
60
55
|
end
|
61
56
|
|
62
|
-
def set(key, value, expiry =
|
57
|
+
def set(key, value, expiry = 0)
|
63
58
|
key = key.to_s
|
64
|
-
@data[key]
|
65
|
-
|
59
|
+
@data[key] = value
|
60
|
+
if expiry.kind_of?(Time)
|
61
|
+
@expiry[key] = expiry
|
62
|
+
else
|
63
|
+
expiry = expiry.to_i
|
64
|
+
@expiry[key] = expiry == 0 ? nil : Time.now + expiry
|
65
|
+
end
|
66
66
|
value
|
67
67
|
end
|
68
68
|
|
69
|
-
def add(key, value, expiry =
|
69
|
+
def add(key, value, expiry = 0)
|
70
70
|
return nil if get(key)
|
71
71
|
set(key, value, expiry)
|
72
72
|
end
|
73
73
|
|
74
|
-
def replace(key, value, expiry =
|
74
|
+
def replace(key, value, expiry = 0)
|
75
75
|
return nil if get(key).nil?
|
76
76
|
set(key, value, expiry)
|
77
77
|
end
|
data/lib/memcache/pg_server.rb
CHANGED
@@ -153,7 +153,11 @@ class Memcache
|
|
153
153
|
end
|
154
154
|
|
155
155
|
def expiry_sql(expiry)
|
156
|
-
expiry
|
156
|
+
if expiry.kind_of?(Time)
|
157
|
+
quote(expiry.to_s(:db))
|
158
|
+
else
|
159
|
+
expiry == 0 ? 'NULL' : "NOW() + interval '#{expiry} seconds'"
|
160
|
+
end
|
157
161
|
end
|
158
162
|
end
|
159
163
|
end
|
data/memcache.gemspec
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{memcache}
|
8
|
+
s.version = "0.9.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Justin Balthrop"]
|
12
|
+
s.date = %q{2009-09-16}
|
13
|
+
s.description = %q{Ruby client for memcached supporting advanced protocol features and pluggable architecture.}
|
14
|
+
s.email = %q{code@justinbalthrop.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
"LICENSE",
|
21
|
+
"README.rdoc",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"lib/memcache.rb",
|
25
|
+
"lib/memcache/local_server.rb",
|
26
|
+
"lib/memcache/migration.rb",
|
27
|
+
"lib/memcache/null_server.rb",
|
28
|
+
"lib/memcache/pg_server.rb",
|
29
|
+
"lib/memcache/segmented_server.rb",
|
30
|
+
"lib/memcache/server.rb",
|
31
|
+
"memcache.gemspec",
|
32
|
+
"test/memcache_local_server_test.rb",
|
33
|
+
"test/memcache_null_server_test.rb",
|
34
|
+
"test/memcache_pg_server_test.rb",
|
35
|
+
"test/memcache_segmented_server_test.rb",
|
36
|
+
"test/memcache_server_test.rb",
|
37
|
+
"test/memcache_server_test_helper.rb",
|
38
|
+
"test/memcache_test.rb",
|
39
|
+
"test/test_helper.rb"
|
40
|
+
]
|
41
|
+
s.homepage = %q{http://github.com/ninjudd/memcache}
|
42
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
43
|
+
s.require_paths = ["lib"]
|
44
|
+
s.rubygems_version = %q{1.3.5}
|
45
|
+
s.summary = %q{Advanced ruby memcache client}
|
46
|
+
s.test_files = [
|
47
|
+
"test/memcache_local_server_test.rb",
|
48
|
+
"test/memcache_null_server_test.rb",
|
49
|
+
"test/memcache_pg_server_test.rb",
|
50
|
+
"test/memcache_segmented_server_test.rb",
|
51
|
+
"test/memcache_server_test.rb",
|
52
|
+
"test/memcache_server_test_helper.rb",
|
53
|
+
"test/memcache_test.rb",
|
54
|
+
"test/test_helper.rb"
|
55
|
+
]
|
56
|
+
|
57
|
+
if s.respond_to? :specification_version then
|
58
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
59
|
+
s.specification_version = 3
|
60
|
+
|
61
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
62
|
+
else
|
63
|
+
end
|
64
|
+
else
|
65
|
+
end
|
66
|
+
end
|
@@ -3,7 +3,7 @@ require 'rubygems'
|
|
3
3
|
require File.dirname(__FILE__) + '/memcache_server_test_helper'
|
4
4
|
require File.dirname(__FILE__) + '/../lib/memcache/pg_server'
|
5
5
|
|
6
|
-
class
|
6
|
+
class MemcachePGServerTest < Test::Unit::TestCase
|
7
7
|
ActiveRecord::Base.establish_connection(
|
8
8
|
:adapter => "postgresql",
|
9
9
|
:host => "localhost",
|
data/test/memcache_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require File.dirname(__FILE__) + '/test_helper'
|
3
3
|
|
4
|
-
class
|
4
|
+
class MemcacheTest < Test::Unit::TestCase
|
5
5
|
PORTS = [11212, 11213, 11214, 11215, 11216, 11217]
|
6
6
|
|
7
7
|
def m
|
@@ -166,10 +166,10 @@ class MemcacheServerTest < Test::Unit::TestCase
|
|
166
166
|
|
167
167
|
def test_expiry
|
168
168
|
100.times do |i|
|
169
|
-
m.set("int#{i}", i, :expiry =>
|
169
|
+
m.set("int#{i}", i, :expiry => 1)
|
170
170
|
assert_equal i, m.get("int#{i}")
|
171
171
|
|
172
|
-
m.set("time#{i}", i, :expiry => Time.now +
|
172
|
+
m.set("time#{i}", i, :expiry => Time.now + 1)
|
173
173
|
assert_equal i, m.get("time#{i}")
|
174
174
|
end
|
175
175
|
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ninjudd-memcache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Balthrop
|
@@ -23,6 +23,7 @@ extra_rdoc_files:
|
|
23
23
|
- LICENSE
|
24
24
|
- README.rdoc
|
25
25
|
files:
|
26
|
+
- LICENSE
|
26
27
|
- README.rdoc
|
27
28
|
- Rakefile
|
28
29
|
- VERSION
|
@@ -33,9 +34,7 @@ files:
|
|
33
34
|
- lib/memcache/pg_server.rb
|
34
35
|
- lib/memcache/segmented_server.rb
|
35
36
|
- lib/memcache/server.rb
|
36
|
-
-
|
37
|
-
- lib/memcache_mock.rb
|
38
|
-
- lib/memcache_util.rb
|
37
|
+
- memcache.gemspec
|
39
38
|
- test/memcache_local_server_test.rb
|
40
39
|
- test/memcache_null_server_test.rb
|
41
40
|
- test/memcache_pg_server_test.rb
|
@@ -44,10 +43,6 @@ files:
|
|
44
43
|
- test/memcache_server_test_helper.rb
|
45
44
|
- test/memcache_test.rb
|
46
45
|
- test/test_helper.rb
|
47
|
-
- test/test_mem_cache.rb
|
48
|
-
- test/test_memcache_extended.rb
|
49
|
-
- test/test_memcache_mock.rb
|
50
|
-
- LICENSE
|
51
46
|
has_rdoc: false
|
52
47
|
homepage: http://github.com/ninjudd/memcache
|
53
48
|
licenses:
|
@@ -84,6 +79,3 @@ test_files:
|
|
84
79
|
- test/memcache_server_test_helper.rb
|
85
80
|
- test/memcache_test.rb
|
86
81
|
- test/test_helper.rb
|
87
|
-
- test/test_mem_cache.rb
|
88
|
-
- test/test_memcache_extended.rb
|
89
|
-
- test/test_memcache_mock.rb
|
data/lib/memcache_extended.rb
DELETED
@@ -1,120 +0,0 @@
|
|
1
|
-
# Need to override entire class with Justin's changes
|
2
|
-
require File.dirname(__FILE__) + '/memcache'
|
3
|
-
|
4
|
-
module MemCacheExtensions
|
5
|
-
LOCK_TIMEOUT = 5 if not defined? LOCK_TIMEOUT
|
6
|
-
WRITE_LOCK_WAIT = 0.001 if not defined? WRITE_LOCK_WAIT
|
7
|
-
|
8
|
-
def get_some(keys, opts = {})
|
9
|
-
opts[:expiry] ||= default_expiry
|
10
|
-
keys = keys.collect {|key| key.to_s}
|
11
|
-
|
12
|
-
records = {}
|
13
|
-
records = self.get_multi(keys) unless opts[:disable]
|
14
|
-
if opts[:validation]
|
15
|
-
records.delete_if do |key, value|
|
16
|
-
not opts[:validation].call(key, value)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
keys_to_fetch = keys - records.keys
|
20
|
-
|
21
|
-
if keys_to_fetch.any?
|
22
|
-
yield(keys_to_fetch).each do |key, data_item|
|
23
|
-
self.set(key, data_item, opts[:expiry]) unless opts[:disable] or opts[:disable_write]
|
24
|
-
records[key] = data_item
|
25
|
-
end
|
26
|
-
end
|
27
|
-
records
|
28
|
-
end
|
29
|
-
|
30
|
-
def in_namespace(namespace)
|
31
|
-
begin
|
32
|
-
# Temporarily change the namespace for convenience.
|
33
|
-
old_namespace = self.namespace
|
34
|
-
self.namespace = "#{old_namespace}#{namespace}"
|
35
|
-
yield
|
36
|
-
ensure
|
37
|
-
self.namespace = old_namespace
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def get_or_set(key)
|
42
|
-
get(key) || begin
|
43
|
-
value = yield
|
44
|
-
set(key, value)
|
45
|
-
value
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def get_reset_expiry(key, expiry)
|
50
|
-
result = get(key)
|
51
|
-
set(key, result, expiry) if result
|
52
|
-
result
|
53
|
-
end
|
54
|
-
|
55
|
-
def lock(key)
|
56
|
-
# Returns true if the lock already exists.
|
57
|
-
response = add(lock_key(key), true, LOCK_TIMEOUT)
|
58
|
-
response.index('STORED') != 0
|
59
|
-
end
|
60
|
-
|
61
|
-
def unlock(key)
|
62
|
-
response = delete(lock_key(key))
|
63
|
-
response.index('DELETED') == 0
|
64
|
-
end
|
65
|
-
|
66
|
-
def with_lock(key, flag = nil)
|
67
|
-
while lock(key) do
|
68
|
-
return if flag == :ignore
|
69
|
-
sleep(WRITE_LOCK_WAIT) # just wait
|
70
|
-
end
|
71
|
-
yield
|
72
|
-
unlock(key) unless flag == :keep
|
73
|
-
end
|
74
|
-
|
75
|
-
def lock_key(key)
|
76
|
-
"lock:#{key}"
|
77
|
-
end
|
78
|
-
|
79
|
-
def locked?(key)
|
80
|
-
not get(lock_key(key)).nil?
|
81
|
-
end
|
82
|
-
|
83
|
-
def set_with_lock(*args)
|
84
|
-
with_lock(args.first, :ignore) do
|
85
|
-
set(*args)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def add_with_lock(*args)
|
90
|
-
with_lock(args.first, :ignore) do
|
91
|
-
add(*args)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def delete_with_lock(*args)
|
96
|
-
# leave a :delete lock around to prevent someone from
|
97
|
-
# adding stale data for a little while
|
98
|
-
with_lock(args.first, :keep) do
|
99
|
-
delete(*args)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def clear
|
104
|
-
flush_all
|
105
|
-
end
|
106
|
-
|
107
|
-
### To support using memcache in testing.
|
108
|
-
def empty?; false; end
|
109
|
-
###
|
110
|
-
end
|
111
|
-
|
112
|
-
class MemCache
|
113
|
-
include MemCacheExtensions
|
114
|
-
end
|
115
|
-
|
116
|
-
if defined?(MemCacheMock)
|
117
|
-
class MemCacheMock
|
118
|
-
include MemCacheExtensions
|
119
|
-
end
|
120
|
-
end
|
data/lib/memcache_mock.rb
DELETED
@@ -1,137 +0,0 @@
|
|
1
|
-
class MemCacheMock
|
2
|
-
attr_writer :namespace
|
3
|
-
|
4
|
-
def initialize
|
5
|
-
@data = {}
|
6
|
-
@expiry = {}
|
7
|
-
@auto_clear = false
|
8
|
-
end
|
9
|
-
|
10
|
-
def namespace
|
11
|
-
@namespace.to_s
|
12
|
-
end
|
13
|
-
|
14
|
-
def cache_key(key)
|
15
|
-
"#{namespace}:#{key}"
|
16
|
-
end
|
17
|
-
|
18
|
-
def default_expiry
|
19
|
-
0
|
20
|
-
end
|
21
|
-
|
22
|
-
# Note: This doesn't work exactly like memcache's incr
|
23
|
-
# because MemCacheMock doesn't support raw storage.
|
24
|
-
# This version will work on marshalled data.
|
25
|
-
# This is also not atomic.
|
26
|
-
def incr(key, amount=1)
|
27
|
-
oldval = get(key).to_i or return nil
|
28
|
-
newval = oldval + amount
|
29
|
-
set(key, newval) # Note: Loses the expiry.
|
30
|
-
return newval
|
31
|
-
end
|
32
|
-
|
33
|
-
def decr(key, amount=1)
|
34
|
-
incr(key, amount * -1)
|
35
|
-
end
|
36
|
-
|
37
|
-
def set(*args)
|
38
|
-
do_set(*args)
|
39
|
-
end
|
40
|
-
|
41
|
-
# Note: Raw not implemented.
|
42
|
-
def do_set(key, value, expiry = default_expiry, raw=false)
|
43
|
-
return '' if @auto_clear
|
44
|
-
key = cache_key(key)
|
45
|
-
|
46
|
-
@data[key] = Marshal.dump(value)
|
47
|
-
@expiry[key] = Time.now + expiry if expiry and expiry != 0
|
48
|
-
'STORED'
|
49
|
-
end
|
50
|
-
|
51
|
-
def add(key, value, expiry = 0)
|
52
|
-
return '' if get(key)
|
53
|
-
do_set(key, value, expiry)
|
54
|
-
end
|
55
|
-
|
56
|
-
def kind_of?(type)
|
57
|
-
(type == MemCache) || super
|
58
|
-
end
|
59
|
-
|
60
|
-
def delete(key)
|
61
|
-
key = cache_key(key)
|
62
|
-
@data.delete(key)
|
63
|
-
end
|
64
|
-
|
65
|
-
def clear
|
66
|
-
@data.clear
|
67
|
-
@expiry.clear
|
68
|
-
end
|
69
|
-
|
70
|
-
def reset
|
71
|
-
# do nothing
|
72
|
-
end
|
73
|
-
|
74
|
-
def get_multi(*keys)
|
75
|
-
opts = keys.last.kind_of?(Hash) ? keys.pop : {}
|
76
|
-
keys.flatten!
|
77
|
-
|
78
|
-
hash = {}
|
79
|
-
keys.each do |key|
|
80
|
-
val = get(key)
|
81
|
-
hash[key.to_s] = val if val
|
82
|
-
end
|
83
|
-
hash
|
84
|
-
end
|
85
|
-
|
86
|
-
# Note: Raw not implemented.
|
87
|
-
def get(key, raw=false)
|
88
|
-
key = cache_key(key)
|
89
|
-
clear if @auto_clear
|
90
|
-
if @expiry[key] and Time.now > @expiry[key]
|
91
|
-
@data[key] = nil
|
92
|
-
@expiry[key] = nil
|
93
|
-
end
|
94
|
-
return if not @data[key]
|
95
|
-
Marshal.load(@data[key])
|
96
|
-
end
|
97
|
-
|
98
|
-
def [](key)
|
99
|
-
get(key)
|
100
|
-
end
|
101
|
-
|
102
|
-
def []=(key, value)
|
103
|
-
set(key, value)
|
104
|
-
end
|
105
|
-
|
106
|
-
def empty?
|
107
|
-
@data.empty?
|
108
|
-
end
|
109
|
-
|
110
|
-
def keys
|
111
|
-
@data.keys
|
112
|
-
end
|
113
|
-
|
114
|
-
def auto_clear_on(&block)
|
115
|
-
if block_given?
|
116
|
-
auto_clear_block(true, &block)
|
117
|
-
else
|
118
|
-
@auto_clear = true
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def auto_clear_off(&block)
|
123
|
-
if block_given?
|
124
|
-
auto_clear_block(false, &block)
|
125
|
-
else
|
126
|
-
@auto_clear = false
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
def auto_clear_block(value, &block)
|
131
|
-
old_auto_clear = @auto_clear
|
132
|
-
@auto_clear = value
|
133
|
-
block.call
|
134
|
-
@auto_clear = old_auto_clear
|
135
|
-
end
|
136
|
-
|
137
|
-
end
|