cloud_cache 1.2.3 → 1.3.0

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.
@@ -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