spymemcached 0.2.1-java → 0.3.0-java

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
@@ -15,7 +15,7 @@ module ActiveSupport
15
15
 
16
16
  def read(key, options = nil)
17
17
  super
18
- @cache.get(key, !(options && options[:raw]))
18
+ @cache.get(key, (options && options[:raw]))
19
19
  end
20
20
 
21
21
  # Set the key to the given value. Pass :unless_exist => true if you want to
@@ -23,7 +23,7 @@ module ActiveSupport
23
23
  def write(key, value, options = nil)
24
24
  super
25
25
  method = unless_exist?(options) ? :add : :set
26
- @cache.send(method, key, value, expiry(options).to_i, !(options && options[:raw]))
26
+ @cache.send(method, key, value, expiry(options).to_i, (options && options[:raw]))
27
27
  end
28
28
 
29
29
  def delete(key, options = nil)
@@ -3,62 +3,100 @@ require "spymemcached/memcached-2.5.jar"
3
3
 
4
4
  class Spymemcached
5
5
  java_import "net.spy.memcached.MemcachedClient"
6
+ java_import "net.spy.memcached.transcoders.Transcoder"
7
+ java_import "net.spy.memcached.CachedData"
6
8
  java_import "java.net.InetSocketAddress"
9
+ java_import "java.util.concurrent.TimeUnit"
7
10
 
8
- def initialize(servers)
9
- @client = MemcachedClient.new(servers.map do |s|
11
+ class RubyTranscoder
12
+ include Transcoder
13
+
14
+ def asyncDecode(data)
15
+ false
16
+ end
17
+
18
+ def decode(data)
19
+ Marshal.load(String.from_java_bytes(data.getData))
20
+ end
21
+
22
+ def encode(obj)
23
+ CachedData.new(0, Marshal.dump(obj).to_java_bytes, getMaxSize)
24
+ end
25
+
26
+ def getMaxSize
27
+ CachedData::MAX_SIZE
28
+ end
29
+ end
30
+
31
+
32
+ def initialize(servers, transcoder = RubyTranscoder.new)
33
+ @transcoder = transcoder
34
+ @client = MemcachedClient.new(servers.map do |s|
10
35
  host, port = s.split(":")
11
36
  InetSocketAddress.new(host, port.to_i)
12
37
  end)
13
38
  end
14
39
 
15
- def set(key, value, expiration = 0, marshal = true)
16
- @client.set(key, expiration, marshal(value, marshal))
40
+ def async_set(key, value, expiration = 0, raw = false)
41
+ @client.set(key, expiration, value, transcoder(raw))
17
42
  end
18
43
 
19
- def get(key, marshal = true)
20
- value = @client.get(key)
21
- marshal && value ? marshal_load(value) : value
44
+ def set(key, value, expiration = 0, raw = false)
45
+ with_timeout async_set(key, value, expiration, raw)
46
+ end
47
+
48
+ def async_get(key, raw = false)
49
+ @client.asyncGet(key, transcoder(raw))
50
+ end
51
+
52
+ def get(key, raw = false)
53
+ with_timeout async_get(key, raw)
22
54
  end
23
55
 
24
56
  def incr(key, by = 1)
25
- @client.incr(key, by)
57
+ with_timeout @client.asyncIncr(key, by)
26
58
  end
27
59
 
28
60
  def decr(key, by = 1)
29
- @client.decr(key, by)
61
+ with_timeout @client.asyncDecr(key, by)
30
62
  end
31
63
 
32
64
  def append(key, value)
33
- @client.append(0, key, value).get
65
+ with_timeout @client.append(0, key, value)
34
66
  end
35
67
 
36
68
  def prepend(key, value)
37
- @client.prepend(0, key, value).get
69
+ with_timeout @client.prepend(0, key, value)
38
70
  end
39
71
 
40
- def multiget(keys, marshal = true)
41
- Hash[*@client.getBulk(*keys).map { |k,v| [k, marshal ? marshal_load(v) : v] }.flatten]
72
+ def multiget(keys, raw = false)
73
+ Hash[*with_timeout(@client.asyncGetBulk(keys, transcoder(raw))).to_a.flatten]
42
74
  end
75
+ alias get_multi multiget
43
76
 
44
- def add(key, value, expiration = 0, marshal = true)
45
- @client.add(key, expiration, marshal(value, marshal)).get
77
+ def add(key, value, expiration = 0, raw = false)
78
+ with_timeout @client.add(key, expiration, value, transcoder(raw))
46
79
  end
47
80
 
48
81
  def del(key)
49
- @client.delete(key).get
82
+ with_timeout @client.delete(key)
50
83
  end
84
+ alias delete del
51
85
 
52
86
  def flush
53
87
  @client.flush
54
88
  end
55
89
 
56
90
  private
57
- def marshal(value, marshal)
58
- marshal ? Marshal.dump(value).to_java_bytes : value.to_s
59
- end
91
+ def transcoder(raw = false)
92
+ raw ? @client.transcoder : @transcoder
93
+ end
60
94
 
61
- def marshal_load(value)
62
- Marshal.load(String.from_java_bytes(value))
95
+ def with_timeout(future, timeout = 0, unit = TimeUnit::MILLISECONDS)
96
+ if timeout > 0
97
+ future.get(timeout, unit)
98
+ else
99
+ future.get
63
100
  end
101
+ end
64
102
  end
@@ -1,4 +1,5 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'rubygems'
2
3
  require "action_view"
3
4
 
4
5
  describe Spymemcached do
@@ -23,48 +24,48 @@ describe Spymemcached do
23
24
  end
24
25
 
25
26
  it "increments keys" do
26
- @cache.set("number", "1", 0, false)
27
+ @cache.set("number", "1", 0, true)
27
28
  @cache.incr("number")
28
- @cache.get("number", false).should == "2"
29
+ @cache.get("number", true).should == "2"
29
30
  end
30
31
 
31
32
  it "increments keys by a set amount" do
32
- @cache.set("number", "1", 0, false)
33
+ @cache.set("number", "1", 0, true)
33
34
  @cache.incr("number", 2)
34
- @cache.get("number", false).should == "3"
35
+ @cache.get("number", true).should == "3"
35
36
  end
36
37
 
37
38
  it "decrements keys" do
38
- @cache.set("number", "2", 0, false)
39
+ @cache.set("number", "2", 0, true)
39
40
  @cache.decr("number")
40
- @cache.get("number", false).should == "1"
41
+ @cache.get("number", true).should == "1"
41
42
  end
42
43
 
43
44
  it "decrements keys by a set amount" do
44
- @cache.set("number", "2", 0, false)
45
+ @cache.set("number", "2", 0, true)
45
46
  @cache.decr("number", 2)
46
- @cache.get("number", false).should == "0"
47
+ @cache.get("number", true).should == "0"
47
48
  end
48
49
 
49
50
  it "appends to keys" do
50
- @cache.set("appendtome", "a", 0, false)
51
+ @cache.set("appendtome", "a", 0, true)
51
52
  @cache.append("appendtome", "b")
52
- @cache.get("appendtome", false).should == "ab"
53
+ @cache.get("appendtome", true).should == "ab"
53
54
  end
54
55
 
55
56
  it "prepends to keys" do
56
- @cache.set("prependtome", "b", 0, false)
57
+ @cache.set("prependtome", "b", 0, true)
57
58
  @cache.prepend("prependtome", "a")
58
- @cache.get("prependtome", false).should == "ab"
59
+ @cache.get("prependtome", true).should == "ab"
59
60
  end
60
61
 
61
62
  it "returns boolean for prepend" do
62
- @cache.set("prependtome", "b", 0, false)
63
+ @cache.set("prependtome", "b", 0, true)
63
64
  @cache.prepend("prependtome", "a").should == true
64
65
  end
65
66
 
66
67
  it "returns boolean for append" do
67
- @cache.set("appendtome", "b", 0, false)
68
+ @cache.set("appendtome", "b", 0, true)
68
69
  @cache.append("appendtome", "a").should == true
69
70
  end
70
71
 
@@ -107,16 +108,6 @@ describe Spymemcached do
107
108
  @cache.get("a").should == {:a => "b"}
108
109
  end
109
110
 
110
- it "supports setting and getting keys without marshalling the data" do
111
- @cache.set("a", {:a => "b"}, 0, false)
112
- @cache.get("a", false).should == {:a => "b"}.to_s
113
- end
114
-
115
- it "supports adding keys without marshalling the data" do
116
- @cache.add("a", {:a => "b"}, 0, false)
117
- @cache.get("a", false).should == {:a => "b"}.to_s
118
- end
119
-
120
111
  # not sure exactly why, but ActionView::SafeBuffer
121
112
  # is the only repeatable instance of this bug that
122
113
  # I can find
@@ -126,4 +117,21 @@ describe Spymemcached do
126
117
  @cache.get("a").should == s
127
118
  @cache.multiget(["a"]).should == {"a" => s}
128
119
  end
120
+
121
+ it "supports configurable transcoders" do
122
+ class NonsenseTranscoder < Spymemcached::RubyTranscoder
123
+ def decode(data)
124
+ "decoded"
125
+ end
126
+
127
+ def encode(object)
128
+ Spymemcached::CachedData.new(0, "encoded".to_java_bytes, getMaxSize)
129
+ end
130
+ end
131
+
132
+ @cache = Spymemcached.new(["localhost:11211"], NonsenseTranscoder.new)
133
+ @cache.set("a", "b")
134
+ @cache.get("a", true).should == "encoded"
135
+ @cache.get("a").should == "decoded"
136
+ end
129
137
  end
@@ -5,12 +5,12 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{spymemcached}
8
- s.version = "0.2.1"
8
+ s.version = "0.3.0"
9
9
  s.platform = %q{java}
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.authors = ["James Golick"]
13
- s.date = %q{2010-09-27}
13
+ s.date = %q{2010-09-28}
14
14
  s.description = %q{A jruby-only memcached client and rails cache store that uses spymemcached under the hood.}
15
15
  s.email = %q{jamesgolick@gmail.com}
16
16
  s.extra_rdoc_files = [
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
8
- - 1
9
- version: 0.2.1
7
+ - 3
8
+ - 0
9
+ version: 0.3.0
10
10
  platform: java
11
11
  authors:
12
12
  - James Golick
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-09-27 00:00:00 -07:00
17
+ date: 2010-09-28 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency