cloud_cache 1.2.3 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,11 @@
1
- = cloud_cache
1
+ = CloudCache - caching in the cloud
2
+
3
+ - Infinite size cache in the cloud
4
+ - High performance
5
+ - Introspection (memcached doesn't have it)
6
+ - No maintenance
7
+ - No worries
8
+ - Free 5MB Cache!
2
9
 
3
10
  http://www.quetzall.com/
4
11
 
@@ -6,21 +13,18 @@ http://www.quetzall.com/
6
13
 
7
14
  Instant memcached, no servers required! See www.quetzall.com for more information.
8
15
 
9
- == FEATURES/PROBLEMS:
10
-
11
- * FIX (list of features or problems)
16
+ == INSTALL:
12
17
 
13
- == SYNOPSIS:
18
+ Be sure you have the new http://gemcutter.org source ABOVE rubyforge.org, then:
14
19
 
15
- FIX (code sample of usage)
20
+ gem install cloud_cache
16
21
 
17
- == REQUIREMENTS:
22
+ Get your CloudCache credentials for free at www.quetzall.com, then:
18
23
 
19
- * FIX (list of requirements)
24
+ config.cache_store = CloudCache.new(CC_ACCESS_KEY, CC_SECRET_KEY)
20
25
 
21
- == INSTALL:
26
+ That's it! Now start caching as you normally would and CloudCache handles the rest.
22
27
 
23
- sudo gem install activesupport
24
28
 
25
29
  == LICENSE:
26
30
 
data/lib/cloud_cache.rb CHANGED
@@ -2,6 +2,7 @@ require 'rubygems'
2
2
  require 'active_support'
3
3
  require 'net/http'
4
4
  require 'base64'
5
+ require 'right_http_connection'
5
6
 
6
7
  $:.unshift(File.dirname(__FILE__))
7
8
 
@@ -17,14 +18,30 @@ end
17
18
 
18
19
  class CloudCache < ActiveSupport::Cache::Store
19
20
 
21
+ DEFAULT_TTL = 0
22
+ DEFAULT_HOST = "cloudcache.ws"
23
+ DEFAULT_PORT = "80"
24
+ DEFAULT_PROTOCOL = "http"
20
25
 
21
- attr_accessor :secret_key
26
+ attr_accessor :access_key, :secret_key, :host, :port, :protocol, :pipeline, :default_ttl
22
27
 
23
- def initialize(access_key, secret_key)
24
- puts 'Creating new CloudCache'
28
+ def initialize(access_key, secret_key, options={})
25
29
  @access_key = access_key
26
30
  @secret_key = secret_key
27
31
 
32
+ @host = options[:host] || DEFAULT_HOST
33
+ @port = options[:port] || DEFAULT_PORT
34
+ @protocol = options[:protocol] || DEFAULT_PROTOCOL
35
+
36
+ @default_ttl = options[:default_ttl] || DEFAULT_TTL
37
+ @pipeline = options[:pipeline] || false
38
+
39
+ puts 'Creating new CloudCache [host=' + @host + ', default_ttl=' + @default_ttl.to_s + ', pipelining=' + @pipeline.to_s + ']'
40
+
41
+ end
42
+
43
+ def pipelined?
44
+ @pipeline
28
45
  end
29
46
 
30
47
  def run_http(http_method, command_name, command_path, body=nil, parameters=nil, extra_headers=nil)
@@ -32,8 +49,8 @@ class CloudCache < ActiveSupport::Cache::Store
32
49
  # puts 'timestamp = ' + ts
33
50
  sig = generate_signature("CloudCache", command_name, ts, @secret_key)
34
51
  # puts "My signature = " + sig
35
- url = "http://cloudcache.ws/" + command_path
36
- # puts url
52
+ url = @protocol + "://" + @host + "/" + command_path # todo: append port if non standard
53
+ # puts url
37
54
 
38
55
  user_agent = "CloudCache Ruby Client"
39
56
  headers = {'User-Agent' => user_agent, 'signature' => sig, 'timestamp' => ts, 'akey' => @access_key}
@@ -44,7 +61,6 @@ class CloudCache < ActiveSupport::Cache::Store
44
61
  end
45
62
  end
46
63
 
47
-
48
64
  uri = URI.parse(url)
49
65
  #puts 'body=' + body.to_s
50
66
  if (http_method == :put)
@@ -73,10 +89,23 @@ class CloudCache < ActiveSupport::Cache::Store
73
89
  # req.each_header do |k, v|
74
90
  # puts 'header ' + k + '=' + v
75
91
  #end
76
- res = Net::HTTP.start(uri.host, uri.port) do |http|
77
- http.request(req)
92
+ if pipelined?
93
+ unless @http_conn
94
+ @http_conn = Rightscale::HttpConnection.new()
95
+ end
96
+
97
+ req_params = { :request => req,
98
+ :server => @host,
99
+ :port => @port,
100
+ :protocol => @protocol }
101
+ res = @http_conn.request(req_params)
102
+ else
103
+ res = Net::HTTP.start(uri.host, uri.port) do |http|
104
+ http.request(req)
105
+ end
78
106
  end
79
- #puts 'response body=' + res.body
107
+
108
+ # puts 'response body=' + res.body
80
109
  case res
81
110
  when Net::HTTPSuccess
82
111
  #puts 'response body=' + res.body
@@ -221,7 +250,7 @@ class CloudCache < ActiveSupport::Cache::Store
221
250
  put(name, value, options)
222
251
  end
223
252
 
224
- def delete(name, options = nil)
253
+ def delete(name, options={})
225
254
  super
226
255
  begin
227
256
  run_http(:delete, "DELETE", name)
@@ -291,6 +320,9 @@ class CloudCache < ActiveSupport::Cache::Store
291
320
 
292
321
  def close
293
322
  # close http connection if it exists.
323
+ if @http_conn
324
+ @http_conn.finish
325
+ end
294
326
  end
295
327
 
296
328
 
data/test/cache_tests.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  require 'test/unit'
2
- require '../lib/cloud_cache'
3
- require 'my_class'
2
+ require File.join(File.dirname(__FILE__), '/../lib/cloud_cache')
3
+ require 'my_class.rb'
4
4
  #
5
- # You'll need make a cloudcache.yml file in this directory that contains:
6
- # amazon:
5
+ # You'll need make a ~/.test-configs/cloud_cache.yml file that contains:
6
+ # cloud_cache:
7
7
  # access_key: ACCESS_KEY
8
8
  # secret_key: SECRET
9
9
  #
@@ -11,19 +11,16 @@ class CacheTests < Test::Unit::TestCase
11
11
 
12
12
  def setup
13
13
  puts("Setting up cache...")
14
- props = nil
15
- begin
16
- props = YAML::load(File.read('cloudcache.yml'))
17
- rescue
18
- raise "Couldn't find cloudcache.yml file. " + $!.message
19
- end
20
- @cache = ActiveSupport::Cache::CloudCache.new(props['access_key'], props['secret_key'])
14
+ @config = YAML::load(File.open(File.expand_path("~/.test-configs/cloud_cache.yml")))
15
+ #puts @config.inspect
16
+ @cache = CloudCache.new(@config['cloud_cache']['access_key'], @config['cloud_cache']['secret_key'])
21
17
  end
22
18
 
23
19
  def teardown
24
20
  @cache.shutdown unless @cache.nil?
25
21
  end
26
22
 
23
+
27
24
  def test_auth
28
25
  @cache.auth()
29
26
  end
@@ -189,7 +186,19 @@ class CacheTests < Test::Unit::TestCase
189
186
  assert_equal("Travis", vz["m4"].name)
190
187
  assert_equal(10, vz["m4"].age)
191
188
 
189
+ kz = ["m1", "should_not_exist", "m3"]
190
+ vz = @cache.get_multi(kz)
191
+ puts 'VZ=' + vz.inspect
192
+ assert vz.size == 2
193
+ assert vz["should_not_exist"].nil?
192
194
 
195
+ @cache.delete("m1")
196
+ vz = @cache.get_multi(kz)
197
+ puts 'VZ=' + vz.inspect
198
+ assert vz.size == 1
199
+ assert vz["m1"].nil?
200
+ assert vz["should_not_exist"].nil?
201
+ assert !vz["m3"].nil?
193
202
  end
194
203
 
195
204
  def test_big
@@ -313,6 +322,29 @@ bmNvZGluZz0iVVRGLTgiPz4KPHJlc3BvbnNlPgogIDxtc2c+Y29udGludWU8
313
322
  L21zZz4KPC9yZXNwb25zZT4KBjsMQBc6E0BlcnJvcl9tZXNzYWdlMDoMQGFj
314
323
  dGlvbkkiCXBlcmYGOwxAFw==", :raw=>true)
315
324
  end
325
+
326
+
327
+ def test_pipeline_vs_non
328
+ to_put = "I am a testing string. Take me apart and put me back together again."
316
329
 
330
+ @cache.pipeline = false
331
+ start = Time.now
332
+ 100.times do |i|
333
+ @cache.put("k_#{i}", to_put)
334
+ end
335
+ duration1 = Time.now - start
336
+ puts 'non-pipelined duration=' + duration1.to_s
337
+ sleep(1)
338
+
339
+ @cache.pipeline = true
340
+ start = Time.now
341
+ 100.times do |i|
342
+ @cache.put("k_#{i}", to_put)
343
+ end
344
+ duration2 = Time.now - start
345
+ puts 'pipelined duration=' + duration2.to_s
346
+
347
+ assert duration2 < duration1, "Pipelined was slower?? " + duration2.to_s + " slower than " + duration1.to_s
348
+ end
317
349
 
318
350
  end
data/test/my_class.rb CHANGED
@@ -1,9 +1,9 @@
1
-
2
- class MyClass
3
- attr_accessor :name, :age
4
-
5
- def initialize(name, age)
6
- @name = name
7
- @age = age
8
- end
1
+
2
+ class MyClass
3
+ attr_accessor :name, :age
4
+
5
+ def initialize(name, age)
6
+ @name = name
7
+ @age = age
8
+ end
9
9
  end
data/test/test_runner.rb CHANGED
@@ -1,10 +1,10 @@
1
- # temporary until rubymine supports ruby 1.i
2
-
3
- #require 'test/unit'
4
- #require 'cache_tests'
5
-
6
- #t = CacheTests.new("test_get_multi")
7
- #Test::Unit::UI::Console::TestRunner.run(CacheTests)
8
- #t.setup
9
- #t.test_counters
10
- #t.teardown
1
+ # temporary until rubymine supports ruby 1.i
2
+
3
+ #require 'test/unit'
4
+ #require 'cache_tests'
5
+
6
+ #t = CacheTests.new("test_get_multi")
7
+ #Test::Unit::UI::Console::TestRunner.run(CacheTests)
8
+ #t.setup
9
+ #t.test_counters
10
+ #t.teardown
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloud_cache
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Travis Reeder
@@ -9,10 +9,19 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-09-21 00:00:00 -07:00
12
+ date: 2009-11-25 00:00:00 -08:00
13
13
  default_executable:
14
- dependencies: []
15
-
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: http_connection
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
16
25
  description: Client library for Quetzall's CloudCache service.
17
26
  email: travis@appoxy.com
18
27
  executables: []
@@ -20,12 +29,12 @@ executables: []
20
29
  extensions: []
21
30
 
22
31
  extra_rdoc_files:
23
- - README.txt
32
+ - README.markdown
24
33
  files:
25
34
  - lib/cloud_cache.rb
26
35
  - lib/hmac-sha1.rb
27
36
  - lib/hmac.rb
28
- - README.txt
37
+ - README.markdown
29
38
  has_rdoc: true
30
39
  homepage: http://github.com/quetzall/cloud_cache/
31
40
  licenses: []
@@ -52,7 +61,7 @@ requirements: []
52
61
  rubyforge_project:
53
62
  rubygems_version: 1.3.5
54
63
  signing_key:
55
- specification_version: 2
64
+ specification_version: 3
56
65
  summary: Client library for Quetzall's CloudCache service.
57
66
  test_files:
58
67
  - test/cache_tests.rb