jruby-ehcache 0.5.0 → 1.0.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.
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