jruby-ehcache 0.5.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt CHANGED
@@ -1,14 +1,14 @@
1
- = Ehcache for JRuby
1
+ = jruby-ehcache - Ehcache for JRuby
2
2
 
3
3
  http://github.com/dylanz/ehcache
4
4
 
5
5
  == DESCRIPTION:
6
6
 
7
- Ehcache is a simplified JRuby interface to Java's (JSR-107 compliant) Ehcache.
8
- Simplified meaning that it should work out-of-the-box, but a lot of native
9
- methods haven't been interfaced yet, as they weren't needed. Configuration
10
- occurs in config/ehcache.yml, and should support all the configuration
11
- options available.
7
+ jruby-ehcache is a JRuby interface to Java's (JSR-107 compliant) Ehcache.
8
+ It provides 100% full coverage of the native Ehcache API and also provides
9
+ some Rubyesque enhancements to make it idiomatic to Ruby developers.
10
+ Configuration is done with the traditional ehcache.xml file that Java
11
+ developers use.
12
12
 
13
13
  Some biased and non-biased Ehcache VS Memcache articles:
14
14
  http://gregluck.com/blog/archives/2007/05/comparing_memca.html
@@ -30,33 +30,35 @@ http://dylanz.lighthouseapp.com/projects/14518-ehcache-jruby/overview
30
30
 
31
31
 
32
32
  == BASIC USAGE:
33
-
33
+ require 'ehcache'
34
34
  manager = CacheManager.new
35
35
  cache = manager.cache
36
36
  cache.put("key", "value", {:ttl => 120})
37
- cache.get("key")
37
+ cache.get("key") # => returns the Ehcache Element object
38
+ cache["key"] # => returns "value", the value of the Element
38
39
  manager.shutdown
39
40
 
40
41
 
41
42
  == RAILS:
42
43
 
43
- Rails 2 and Rails 3 integration are provided by the separate ehcache-rails2
44
- and ehcache-rails3 gems. To install, choose the correct version for your
45
- Rails application and use JRuby's gem command to install, e.g.:
44
+ Rails 2 and Rails 3 integration are provided by the separate
45
+ jruby-ehcache-rails2 and jruby-ehcache-rails3 gems. To install, choose the
46
+ correct version for your Rails application and use JRuby's gem command to
47
+ install, e.g.:
46
48
 
47
- $ jgem install ehcache-rails3
49
+ $ jgem install jruby-ehcache-rails3
48
50
  OR
49
- $ jruby -S gem install ehcache-rails3
51
+ $ jruby -S gem install jruby-ehcache-rails3
50
52
 
51
53
 
52
54
  == REQUIREMENTS:
53
55
 
54
- Tested with JRuby 1.5.0.
56
+ Tested with JRuby 1.5.3.
55
57
 
56
58
 
57
59
  == INSTALL:
58
60
 
59
- $ sudo jruby -S gem install ehcache
61
+ $ sudo jruby -S gem install jruby-ehcache
60
62
 
61
63
 
62
64
  == LICENSE:
data/Rakefile CHANGED
@@ -1,3 +1,15 @@
1
+ require 'rake/testtask'
2
+ require 'rake/rdoctask'
3
+
4
+ task :default => [ :test ]
5
+
6
+ desc "Executes the test suite"
7
+ Rake::TestTask.new do |t|
8
+ t.name = :test
9
+ t.libs << 'lib' << 'ext' << 'test'
10
+ t.pattern = "test/test_*.rb"
11
+ end
12
+
1
13
  begin
2
14
  require 'jeweler'
3
15
  rescue LoadError
@@ -18,29 +30,31 @@ Jeweler::Tasks.new do |gemspec|
18
30
  gemspec.description = "JRuby interface to the popular Java caching library Ehcache"
19
31
  gemspec.files.exclude '.gitignore'
20
32
 
21
- # These files go in the ehcache-rails2 and ehcache-rails3 gems
33
+ # These files go in the jruby-ehcache-rails2 and jruby-ehcache-rails3 gems
22
34
  gemspec.files.exclude 'lib/ehcache_store.rb'
23
35
  gemspec.files.exclude 'lib/active_support/**/*'
36
+ gemspec.files.exclude 'lib/ehcache/rails'
37
+ gemspec.add_dependency 'activesupport'
24
38
  end
25
39
 
26
40
  Jeweler::Tasks.new do |gemspec|
27
41
  defaults(gemspec)
28
- gemspec.name = 'ehcache-rails3'
42
+ gemspec.name = 'jruby-ehcache-rails3'
29
43
  gemspec.summary = 'Rails 3 cache store provider using Ehcache'
30
44
  gemspec.description = 'Rails 3 cache store provider using Ehcache'
31
- gemspec.files = 'lib/active_support/**/*'
45
+ gemspec.files = FileList['lib/active_support/**/*', 'lib/ehcache/rails/**/*']
32
46
  gemspec.test_files = []
33
- gemspec.add_dependency 'jruby-ehcache', ">=0.5.0"
47
+ gemspec.add_dependency 'jruby-ehcache', ">=1.0.0"
34
48
  end
35
49
 
36
50
  Jeweler::Tasks.new do |gemspec|
37
51
  defaults(gemspec)
38
- gemspec.name = 'ehcache-rails2'
52
+ gemspec.name = 'jruby-ehcache-rails2'
39
53
  gemspec.summary = 'Rails 2 cache store provider using Ehcache'
40
54
  gemspec.description = 'Rails 2 cache store provider using Ehcache'
41
- gemspec.files = 'lib/ehcache_store.rb'
55
+ gemspec.files = FileList['lib/active_support/**/*', 'lib/ehcache/rails/**/*']
42
56
  gemspec.test_files = []
43
- gemspec.add_dependency 'jruby-ehcache', ">=0.5.0"
57
+ gemspec.add_dependency 'jruby-ehcache', ">=1.0.0"
44
58
  end
45
59
 
46
60
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.0
1
+ 1.0.0
data/config/ehcache.yml CHANGED
@@ -1,15 +1,15 @@
1
- disk:
1
+ disk_store:
2
2
  path: java.io.tmpdir
3
3
 
4
- peer_provider:
5
- class: net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory
4
+ peer_providers:
5
+ - class: net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory
6
6
  properties: peerDiscovery=automatic,multicastGroupAddress=230.0.0.1,multicastGroupPort=4446,timeToLive=1
7
7
  property_separator: "\,"
8
8
 
9
- peer_listener:
10
- class: net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory
9
+ peer_listeners:
10
+ - class: net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory
11
11
 
12
- default:
12
+ default_cache:
13
13
  name: cache
14
14
  max_elements_in_memory: 10000
15
15
  time_to_live_seconds: 0
@@ -1,16 +1,16 @@
1
- disk:
1
+ disk_store:
2
2
  path: java.io.tmpdir
3
3
 
4
- peer_provider:
5
- class: net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory
4
+ peer_providers:
5
+ - class: net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory
6
6
  properties: peerDiscovery=manual,rmiUrls=//that_hostname:40001/cache
7
7
  property_separator: "\,"
8
8
 
9
- peer_listener:
10
- class: net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory
9
+ peer_listeners:
10
+ - class: net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory
11
11
  properties: hostName=this_hostname,port=40000
12
12
 
13
- default:
13
+ default_cache:
14
14
  name: cache
15
15
  max_elements_in_memory: 10000
16
16
  time_to_live_seconds: 0
@@ -0,0 +1,44 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:noNamespaceSchemaLocation="../../main/config/ehcache.xsd">
5
+
6
+ <!-- Disable for test ehcache.xml. Should go to the same place. -->
7
+ <diskStore path="java.io.tmpdir"/>
8
+
9
+ <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
10
+ properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1, multicastGroupPort=4446, timeToLive=0"/>
11
+
12
+
13
+ <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
14
+ properties="hostName=, port=, socketTimeoutMillis="/>
15
+
16
+
17
+ <defaultCache
18
+ name="default"
19
+ maxElementsInMemory="10"
20
+ eternal="false"
21
+ timeToIdleSeconds="5"
22
+ timeToLiveSeconds="10"
23
+ overflowToDisk="true"
24
+ />
25
+
26
+
27
+ <!-- Sample cache named sampleCache1 -->
28
+ <cache name="sampleCache1"
29
+ maxElementsInMemory="10000"
30
+ maxElementsOnDisk="1000"
31
+ eternal="false"
32
+ timeToIdleSeconds="360"
33
+ timeToLiveSeconds="1000"
34
+ overflowToDisk="true">
35
+ </cache>
36
+
37
+ <!-- Sample cache named sampleCache2. Is eternal. Is diskPersistent but does not overflow to disk -->
38
+ <cache name="sampleCache2"
39
+ maxElementsInMemory="1000"
40
+ eternal="true"
41
+ overflowToDisk="false"
42
+ diskPersistent="true"
43
+ />
44
+ </ehcache>
@@ -0,0 +1,13 @@
1
+ require 'ehcache'
2
+
3
+ manager = Ehcache::CacheManager.new
4
+ cache = manager.cache
5
+
6
+ cache.put("answer", "42", {:ttl => 120})
7
+ answer = cache.get("answer")
8
+ puts "Answer: #{answer}"
9
+
10
+ question = cache.get("question") || 'unknown'
11
+ puts "Question: #{question}"
12
+
13
+ manager.shutdown
data/lib/ehcache.rb CHANGED
@@ -1,5 +1,7 @@
1
- $:.unshift(File.dirname(__FILE__)) unless
2
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
1
+ unless $:.include?(File.dirname(__FILE__)) ||
2
+ $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+ $:.unshift(File.dirname(__FILE__))
4
+ end
3
5
 
4
6
  require 'java'
5
7
 
@@ -12,11 +14,9 @@ module Ehcache
12
14
  class EhcacheError < RuntimeError; end
13
15
  end
14
16
 
17
+ require 'ehcache/extensions'
15
18
  require 'ehcache/java'
16
19
  require 'ehcache/config'
17
20
  require 'ehcache/cache'
18
21
  require 'ehcache/cache_manager'
19
22
  require 'ehcache/element'
20
- require 'ehcache/extensions'
21
- require 'ehcache/version'
22
- require 'ehcache/status'
data/lib/ehcache/cache.rb CHANGED
@@ -1,127 +1,58 @@
1
- module Ehcache
2
- class Cache
3
- PRIMARY = "cache"
1
+ # Enhance net.sf.ehcache.Cache with a more Rubyesque API.
2
+ class Java::NetSfEhcache::Cache
3
+ include Enumerable
4
4
 
5
- # pull cache from given manager by name
6
- def initialize(manager, cache_name)
7
- @proxy = manager.get_cache(cache_name)
8
- end
9
-
10
- # put a new element into the cache
11
- def put(key, value, options = {})
12
- if key.nil? || key.empty?
13
- raise EhcacheError, "Element cannot be blank"
14
- end
15
- element = Ehcache::Element.new(key, value, options)
16
- @proxy.put(element.proxy)
17
- rescue NativeException => e
18
- raise EhcacheError, e.cause
19
- end
20
- alias_method :set, :put
21
- alias_method :add, :put
22
-
23
- # another alias for put
24
- def []=(key, value)
25
- put(key, value)
26
- end
27
-
28
- # get an element value from cache by key
29
- def get(key)
30
- element = @proxy.get(key)
31
- element ? element.get_value : nil
32
- rescue NativeException => e
33
- raise EhcacheError, e.cause
34
- end
35
- alias_method :[], :get
36
-
37
- # get an element from cache by key
38
- def element(key)
39
- element = @proxy.get(key)
40
- return nil unless element
41
- Ehcache::Element.new(element.get_key, element.get_value,
42
- {:ttl => element.get_time_to_live })
43
- rescue NativeException => e
44
- raise EhcacheError, e.cause
45
- end
46
-
47
- # remove an element from the cache by key
48
- def remove(key)
49
- @proxy.remove(key)
50
- rescue NativeException => e
51
- raise EhcacheError, e.cause
52
- end
53
- alias_method :delete, :remove
54
-
55
- # remove all elements from the cache
56
- def remove_all
57
- @proxy.remove_all
58
- rescue NativeException => e
59
- raise EhcacheError, e.cause
60
- end
61
- alias_method :clear, :remove_all
62
-
63
- def keys
64
- @proxy.get_keys
65
- end
66
-
67
- def exist?(key)
68
- @proxy.is_key_in_cache(key)
69
- end
70
-
71
- # returns the current status of the cache
72
- def status
73
- @proxy.get_status
74
- end
75
-
76
- def alive?
77
- @proxy.get_status == Status::ALIVE
78
- end
79
-
80
- def shutdown?
81
- @proxy.get_status == Status::SHUTDOWN
82
- end
83
-
84
- def uninitialized?
85
- @proxy.get_status == Status::UNINITIALISED
86
- end
87
-
88
- # number of elements in the cache
89
- def size
90
- @proxy.get_size
91
- end
92
-
93
- # number of elements in the memory store
94
- def memory_size
95
- @proxy.get_memory_store_size
96
- end
97
-
98
- # number of elements in the cache store
99
- def disk_size
100
- @proxy.get_disk_store_size
101
- end
102
-
103
- # TODO: implement statistics !
104
- # return statistics about the cache
105
- def statistics
106
- @proxy.get_statistics
107
- rescue NativeException => e
108
- raise EhcacheError, e.cause
5
+ # Yield each Element stored in this cache to the given block. This method
6
+ # uses Cache#getKeys as its basis, and therefore it is possible that some
7
+ # of the yielded elements have expired.
8
+ def each
9
+ for key in self.getKeys
10
+ yield self.get(key)
109
11
  end
12
+ end
13
+ # Gets an element value from the cache. Unlike the #get method, this method
14
+ # returns the element value, not the Element object.
15
+ def [](key)
16
+ element = self.get(key)
17
+ element ? element.value : nil
18
+ end
110
19
 
111
- def max_elements
112
- @proxy.get_max_elements_in_memory
113
- end
20
+ alias ehcache_put put
114
21
 
115
- def eternal?
116
- @proxy.is_eternal
117
- end
118
-
119
- def ttl
120
- @proxy.get_time_to_live_seconds
22
+ # Wrap the Cache#put method to allow for extra options to be passed to the
23
+ # created Element.
24
+ def put(*args)
25
+ options = args.extract_options!
26
+ if args.size == 1 && args.first.kind_of?(Ehcache::Element)
27
+ element = args.first
28
+ elsif args.size == 2
29
+ element = Ehcache::Element.create(args[0], args[1], options)
30
+ else
31
+ raise ArgumentError, "Must be Element object or key and value arguments"
121
32
  end
33
+ ehcache_put(element)
34
+ end
122
35
 
123
- def tti
124
- @proxy.get_time_to_idle_seconds
125
- end
36
+ alias []= put
37
+
38
+ alias include? isKeyInCache
39
+ alias member? isKeyInCache
40
+
41
+ # Atomic compare and swap for cache elements. Invokes the given block with
42
+ # the current value of the element and attempts to replace it with the
43
+ # value returned from the block, repeating until replace returns true.
44
+ # Note that the provided block works only with element values, not Element
45
+ # objects: the result of element.getValue is passed to the block parameter,
46
+ # and the block is expected to return a value based on it.
47
+ # If there is no element with the given key, returns immediately without
48
+ # retrying.
49
+ def compare_and_swap(key, &block)
50
+ begin
51
+ old_element = self.get(key)
52
+ return nil unless old_element
53
+ new_element = Ehcache::Element.new(key, yield(old_element.value))
54
+ end until replace(old_element, new_element)
126
55
  end
56
+
57
+ alias update compare_and_swap
127
58
  end
@@ -1,65 +1,69 @@
1
- module Ehcache
2
- class CacheManager
3
- def initialize(options={})
4
- # TODO document this
5
- unless options[:security]
6
- import java.lang.System unless defined?(System)
7
- import java.rmi.RMISecurityManager unless defined?(RMISecurityManager)
8
- RMISecurityManager.new if System.getSecurityManager == nil
9
- end
10
- @manager = Ehcache::Java::CacheManager.new(Ehcache::Config.generate(options))
11
- end
12
-
13
- # return cache by name
14
- def cache(cache_name=nil)
15
- Ehcache::Cache.new(@manager, cache_name || Ehcache::Cache::PRIMARY)
16
- end
17
-
18
- # return all cache names
19
- def caches
20
- @manager.get_cache_names
21
- end
1
+ # Enhance net.sf.ehcache.CacheManager with a more Rubyesque API.
2
+ class Java::NetSfEhcache::CacheManager
3
+ include Enumerable
22
4
 
23
- # adds cache based on default configuration
24
- def add_cache(cache_name)
25
- @manager.add_cache(cache_name)
26
- end
5
+ class << self
6
+ alias_method :ehcache_create, :create
27
7
 
28
- # remove cache
29
- def remove(cache_name)
30
- @manager.remove_cache(cache_name)
31
- end
32
-
33
- # remove all caches
34
- def remove_all
35
- @manager.removal_all
8
+ # Enhanced create that provides for some extra configuration options.
9
+ # Specifically, String arguments may be used where native Ehcache expects
10
+ # java.io.File objects, and if the String refers to a YAML file it will be
11
+ # used as the Configuration source.
12
+ def create(*args)
13
+ process_init_args(*args) do |*args|
14
+ ehcache_create(*args)
15
+ end
36
16
  end
17
+ end
37
18
 
38
- # empty all caches
39
- def flush_all
40
- @manager.clear_all
19
+ # Enhanced constructor that provides for some extra configuration options.
20
+ # Specifically, String arguments may be used where native Ehcache expects
21
+ # java.io.File objects, and if the String refers to a YAML file it will be
22
+ # used as the Configuration source.
23
+ def initialize(*args)
24
+ process_init_args(*args) do |*args|
25
+ super(*args)
41
26
  end
27
+ end
42
28
 
43
- def enable_shutdown_hook
44
- @manager.add_shutdown_hook_if_required
29
+ # Iterate through each cache managed by this CacheManager.
30
+ def each
31
+ for name in self.cache_names
32
+ yield self.get_ehcache(name)
45
33
  end
34
+ end
46
35
 
47
- def disable_shutdown_hook
48
- @manager.disable_shutdown_hook
49
- end
36
+ alias [] get_ehcache
50
37
 
51
- def shutdown
52
- @manager.shutdown
53
- end
38
+ def cache(cache_name = '__default_jruby_cache')
39
+ self.add_cache_if_absent(cache_name)
40
+ self.get_ehcache(cache_name)
41
+ end
54
42
 
55
- def status
56
- @manager.get_status.to_s
57
- end
43
+ # true if cache by given name is being managed, false otherwise
44
+ def include?(cache_name)
45
+ self.cache_exists(cache_name)
46
+ end
47
+ alias_method :exists?, :include?
48
+ end
58
49
 
59
- # true if cache by given name is being managed, false otherwise
60
- def include?(cache_name)
61
- @manager.cache_exists(cache_name)
50
+ # Helper method for processing initialization arguments passed to
51
+ # CacheManager.create and CacheManager#initialize.
52
+ def process_init_args(*args)
53
+ args.compact!
54
+ if args.empty?
55
+ # First, look relative to the file that is creating the CacheManager.
56
+ # The expression caller[2] finds the entry in the call stack where
57
+ # CacheManager.new or CacheManager.create was called.
58
+ creator = /^(.+?):\d/.match(caller[2])[1]
59
+ if ehcache_config = Java::NetSfEhcacheConfig::Configuration.find(File.dirname(creator))
60
+ yield(ehcache_config)
61
+ else
62
+ yield
62
63
  end
63
- alias_method :exists?, :include?
64
+ elsif args.size == 1 && args.first.is_a?(String)
65
+ yield(Ehcache::Config::Configuration.create(args.first))
66
+ else
67
+ yield(*args)
64
68
  end
65
69
  end