syncache 1.0.0 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
data/syncache.gemspec CHANGED
@@ -1,63 +1,25 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{syncache}
8
- s.version = "1.0.0"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Dmitry Borodaenko", "David Czarnecki"]
12
- s.date = %q{2010-05-06}
13
- s.description = %q{SynCache::Cache stores cached objects in a Hash that is protected by an advanced two-level locking mechanism. Two-level locking ensures that:
14
-
15
- * Multiple threads can add and fetch objects in parallel without stepping on each other's toes.
16
- * While one thread is working on a cache entry, other threads can access the rest of the cache with no waiting on the global lock, no race conditions nor deadlock or livelock situations.
17
- * While one thread is performing a long and resource-intensive operation, other threads that request the same data with fetch_or_add() method will be put on hold, and as soon as the first thread completes the operation, the result will be returned to all threads. Without this feature, a steady stream of requests with less time between them than it takes to complete one request can easily bury a server under an avalanche of threads all wasting resources on the same expensive operation.
18
-
19
- When number of cache entries exceeds the size limit, the least recently accessed entries are replaced with new data. This replacement strategy is controlled by the SynCache::CacheEntry class and can be changed by overriding its replacement_index() method.
20
-
21
- Cache entries are automatically invalidated when their ttl (time to live) is exceeded. Entries can be explicitly invalidated by flush() method. The method can use === operator to compare cache keys against flush base (so that base can be e.g. a Regexp), and invalidates all entries when invoked without the base parameter.
22
-
23
- The flush_delay initialization option allows to limit cache's flush rate. When this option is set, SynCache will make sure that at least this many seconds (it can also be a fraction) pass between two flushes. When extra flushes are requested, invalidation of flushed entries is postponed until earliest time when next flush is allowed.
24
- }
25
- s.email = %q{angdraug@debian.org}
26
- s.extra_rdoc_files = [
27
- "LICENSE",
28
- "README.rdoc"
29
- ]
30
- s.files = [
31
- ".document",
32
- ".gitignore",
33
- "LICENSE",
34
- "README.rdoc",
35
- "Rakefile",
36
- "VERSION",
37
- "lib/syncache.rb",
38
- "lib/syncache_sync_patch.rb",
39
- "syncache.gemspec",
40
- "test/helper.rb",
41
- "test/test_syncache.rb"
42
- ]
43
- s.homepage = %q{http://github.com/czarneckid/syncache}
44
- s.rdoc_options = ["--charset=UTF-8"]
45
- s.require_paths = ["lib"]
46
- s.rubygems_version = %q{1.3.6}
47
- s.summary = %q{SynCache is a thread-safe time-limited cache with flexible replacement policy and ability to wrap generation of expensive cache entries in synchronized blocks. SynCache was used in the Samizdat open publishing engine since 2005, and now it's released as a stand-alone module ready for use in other applications.}
48
- s.test_files = [
49
- "test/helper.rb",
50
- "test/test_syncache.rb"
51
- ]
52
-
53
- if s.respond_to? :specification_version then
54
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
55
- s.specification_version = 3
56
-
57
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
58
- else
59
- end
60
- else
61
- end
1
+ Gem::Specification.new do |spec|
2
+ spec.name = 'syncache'
3
+ spec.version = '1.2'
4
+ spec.author = 'Dmitry Borodaenko'
5
+ spec.email = 'angdraug@debian.org'
6
+ spec.homepage = 'https://github.com/angdraug/syncache'
7
+ spec.summary = 'Thread-safe time-limited cache with flexible replacement policy'
8
+ spec.description = <<-EOF
9
+ SynCache stores cached objects in a Hash that is protected by an advanced
10
+ two-level locking mechanism which ensures that:
11
+
12
+ * Multiple threads can add and fetch objects in parallel.
13
+ * While one thread is working on a cache entry, other threads can access
14
+ the rest of the cache with no waiting on the global lock, no race
15
+ conditions nor deadlock or livelock situations.
16
+ * While one thread is performing a long and resource-intensive
17
+ operation, other threads that request the same data will be put on hold,
18
+ and as soon as the first thread completes the operation, the result will be
19
+ returned to all threads.
20
+ EOF
21
+ spec.files = `git ls-files`.split "\n"
22
+ spec.test_files = Dir['test/ts_*.rb']
23
+ spec.executables = spec.files.map{|p| p =~ /^bin\/(.*)/ ? $1 : nil }.compact
24
+ spec.license = 'GPL3+'
62
25
  end
63
-
data/test/tc_remote.rb ADDED
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # SynCache tests
4
+ #
5
+ # Copyright (c) 2002-2011 Dmitry Borodaenko <angdraug@debian.org>
6
+ #
7
+ # This program is free software.
8
+ # You can distribute/modify this program under the terms of
9
+ # the GNU General Public License version 3 or later.
10
+ #
11
+ # vim: et sw=2 sts=2 ts=8 tw=0
12
+
13
+ require 'test/unit'
14
+ require 'syncache'
15
+
16
+ include SynCache
17
+
18
+ class TC_RemoteCache < Test::Unit::TestCase
19
+
20
+ def setup
21
+ @server = ::DRb.start_service(nil, Cache.new(0.1, 5))
22
+ @cache = RemoteCache.new(@server.uri, 0.1, 0.01)
23
+ end
24
+
25
+ def teardown
26
+ ::DRb.stop_service
27
+ end
28
+
29
+ def test_flush
30
+ @cache['t'] = 'test'
31
+ @cache.flush
32
+ assert_equal nil, @cache['t']
33
+ end
34
+
35
+ def test_add_fetch
36
+ @cache['t'] = 'test'
37
+ assert_equal 'test', @cache['t']
38
+ end
39
+
40
+ def test_fetch_or_add
41
+ assert_equal nil, @cache['t']
42
+ @cache.fetch_or_add('t') { 'test' }
43
+ assert_equal 'test', @cache['t']
44
+ end
45
+
46
+ def test_size
47
+ 1.upto(5) {|i| @cache[i] = i }
48
+ 1.upto(5) do |i|
49
+ assert_equal i, @cache[i]
50
+ end
51
+ 6.upto(10) {|i| @cache[i] = i }
52
+ 1.upto(5) do |i|
53
+ assert_equal nil, @cache[i]
54
+ end
55
+ end
56
+
57
+ def test_ttl
58
+ 1.upto(5) {|i| @cache[i] = i }
59
+ 1.upto(5) do |i|
60
+ assert_equal i, @cache[i]
61
+ end
62
+ sleep(0.2)
63
+ 1.upto(5) do |i|
64
+ assert_equal nil, @cache[i]
65
+ end
66
+ end
67
+
68
+ def test_timeout
69
+ slow = Thread.new do
70
+ @cache.fetch_or_add('t') { sleep 0.2; 'slow' }
71
+ end
72
+ sleep 0.01
73
+ @cache.fetch_or_add('t') { 'fast' }
74
+ assert_equal 'fast', @cache['t']
75
+ slow.join
76
+ @cache.delete('t')
77
+
78
+ decent = Thread.new do
79
+ @cache.fetch_or_add('t') { sleep 0.03; 'decent' }
80
+ end
81
+ sleep 0.01
82
+ @cache.fetch_or_add('t') { 'fast' }
83
+ assert_equal 'decent', @cache['t']
84
+ decent.join
85
+ end
86
+ end
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # SynCache tests
4
4
  #
5
- # Copyright (c) 2002-2009 Dmitry Borodaenko <angdraug@debian.org>
5
+ # Copyright (c) 2002-2011 Dmitry Borodaenko <angdraug@debian.org>
6
6
  #
7
7
  # This program is free software.
8
8
  # You can distribute/modify this program under the terms of
@@ -10,16 +10,13 @@
10
10
  #
11
11
  # vim: et sw=2 sts=2 ts=8 tw=0
12
12
 
13
- require 'helper'
13
+ require 'test/unit'
14
+ require 'syncache'
14
15
 
15
16
  include SynCache
16
17
 
17
18
  class TC_Cache < Test::Unit::TestCase
18
19
 
19
- def test_initialize
20
- cache = Cache.new(3, 5)
21
- end
22
-
23
20
  def test_flush
24
21
  cache = Cache.new(3, 5)
25
22
  cache['t'] = 'test'
@@ -40,7 +37,7 @@ class TC_Cache < Test::Unit::TestCase
40
37
  assert_equal 'test', cache['t']
41
38
  end
42
39
 
43
- def test_truncate
40
+ def test_size
44
41
  cache = Cache.new(3, 5)
45
42
  1.upto(5) {|i| cache[i] = i }
46
43
  1.upto(5) do |i|
@@ -52,7 +49,7 @@ class TC_Cache < Test::Unit::TestCase
52
49
  end
53
50
  end
54
51
 
55
- def test_timeout
52
+ def test_ttl
56
53
  cache = Cache.new(0.01, 5)
57
54
  1.upto(5) {|i| cache[i] = i }
58
55
  1.upto(5) do |i|
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # SynCache tests
4
+ #
5
+ # Copyright (c) 2002-2011 Dmitry Borodaenko <angdraug@debian.org>
6
+ #
7
+ # This program is free software.
8
+ # You can distribute/modify this program under the terms of
9
+ # the GNU General Public License version 3 or later.
10
+ #
11
+ # vim: et sw=2 sts=2 ts=8 tw=0
12
+
13
+ require 'test/unit'
14
+ require 'test/tc_syncache'
15
+ require 'test/tc_remote'
metadata CHANGED
@@ -1,75 +1,67 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: syncache
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 1
7
- - 0
8
- - 0
9
- version: 1.0.0
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.2'
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Dmitry Borodaenko
13
- - David Czarnecki
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2010-05-06 00:00:00 -04:00
19
- default_executable:
12
+ date: 2012-10-13 00:00:00.000000000 Z
20
13
  dependencies: []
21
-
22
- description: "SynCache::Cache stores cached objects in a Hash that is protected by an advanced two-level locking mechanism. Two-level locking ensures that:\n\n * Multiple threads can add and fetch objects in parallel without stepping on each other's toes.\n * While one thread is working on a cache entry, other threads can access the rest of the cache with no waiting on the global lock, no race conditions nor deadlock or livelock situations.\n * While one thread is performing a long and resource-intensive operation, other threads that request the same data with fetch_or_add() method will be put on hold, and as soon as the first thread completes the operation, the result will be returned to all threads. Without this feature, a steady stream of requests with less time between them than it takes to complete one request can easily bury a server under an avalanche of threads all wasting resources on the same expensive operation.\n\n When number of cache entries exceeds the size limit, the least recently accessed entries are replaced with new data. This replacement strategy is controlled by the SynCache::CacheEntry class and can be changed by overriding its replacement_index() method.\n\n Cache entries are automatically invalidated when their ttl (time to live) is exceeded. Entries can be explicitly invalidated by flush() method. The method can use === operator to compare cache keys against flush base (so that base can be e.g. a Regexp), and invalidates all entries when invoked without the base parameter.\n\n The flush_delay initialization option allows to limit cache's flush rate. When this option is set, SynCache will make sure that at least this many seconds (it can also be a fraction) pass between two flushes. When extra flushes are requested, invalidation of flushed entries is postponed until earliest time when next flush is allowed.\n "
14
+ description: ! "SynCache stores cached objects in a Hash that is protected by an advanced\ntwo-level
15
+ locking mechanism which ensures that:\n\n * Multiple threads can add and fetch objects
16
+ in parallel.\n * While one thread is working on a cache entry, other threads can
17
+ access\n the rest of the cache with no waiting on the global lock, no race\n conditions
18
+ nor deadlock or livelock situations.\n * While one thread is performing a long and
19
+ resource-intensive\n operation, other threads that request the same data will
20
+ be put on hold,\n and as soon as the first thread completes the operation, the
21
+ result will be\n returned to all threads.\n"
23
22
  email: angdraug@debian.org
24
- executables: []
25
-
23
+ executables:
24
+ - syncache-drb
26
25
  extensions: []
27
-
28
- extra_rdoc_files:
29
- - LICENSE
26
+ extra_rdoc_files: []
27
+ files:
28
+ - COPYING
29
+ - ChangeLog.mtn
30
30
  - README.rdoc
31
- files:
32
- - .document
33
- - .gitignore
34
- - LICENSE
35
- - README.rdoc
36
- - Rakefile
37
- - VERSION
31
+ - bin/syncache-drb
38
32
  - lib/syncache.rb
39
- - lib/syncache_sync_patch.rb
33
+ - lib/syncache/remote.rb
34
+ - lib/syncache/syncache.rb
35
+ - man/syncache-drb.1
36
+ - setup.rb
40
37
  - syncache.gemspec
41
- - test/helper.rb
42
- - test/test_syncache.rb
43
- has_rdoc: true
44
- homepage: http://github.com/czarneckid/syncache
45
- licenses: []
46
-
38
+ - test/tc_remote.rb
39
+ - test/tc_syncache.rb
40
+ - test/ts_syncache.rb
41
+ homepage: https://github.com/angdraug/syncache
42
+ licenses:
43
+ - GPL3+
47
44
  post_install_message:
48
- rdoc_options:
49
- - --charset=UTF-8
50
- require_paths:
45
+ rdoc_options: []
46
+ require_paths:
51
47
  - lib
52
- required_ruby_version: !ruby/object:Gem::Requirement
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- segments:
57
- - 0
58
- version: "0"
59
- required_rubygems_version: !ruby/object:Gem::Requirement
60
- requirements:
61
- - - ">="
62
- - !ruby/object:Gem::Version
63
- segments:
64
- - 0
65
- version: "0"
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
66
60
  requirements: []
67
-
68
61
  rubyforge_project:
69
- rubygems_version: 1.3.6
62
+ rubygems_version: 1.8.23
70
63
  signing_key:
71
64
  specification_version: 3
72
- summary: SynCache is a thread-safe time-limited cache with flexible replacement policy and ability to wrap generation of expensive cache entries in synchronized blocks. SynCache was used in the Samizdat open publishing engine since 2005, and now it's released as a stand-alone module ready for use in other applications.
73
- test_files:
74
- - test/helper.rb
75
- - test/test_syncache.rb
65
+ summary: Thread-safe time-limited cache with flexible replacement policy
66
+ test_files:
67
+ - test/ts_syncache.rb
data/.document DELETED
@@ -1,5 +0,0 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
data/.gitignore DELETED
@@ -1,21 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
-
21
- ## PROJECT::SPECIFIC
data/LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2009 David Czarnecki
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile DELETED
@@ -1,63 +0,0 @@
1
- require 'rubygems'
2
- require 'rake'
3
-
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "syncache"
8
- gem.summary = %Q{SynCache is a thread-safe time-limited cache with flexible replacement policy and ability to wrap generation of expensive cache entries in synchronized blocks. SynCache was used in the Samizdat open publishing engine since 2005, and now it's released as a stand-alone module ready for use in other applications.}
9
- gem.description = %Q{SynCache::Cache stores cached objects in a Hash that is protected by an advanced two-level locking mechanism. Two-level locking ensures that:
10
-
11
- * Multiple threads can add and fetch objects in parallel without stepping on each other's toes.
12
- * While one thread is working on a cache entry, other threads can access the rest of the cache with no waiting on the global lock, no race conditions nor deadlock or livelock situations.
13
- * While one thread is performing a long and resource-intensive operation, other threads that request the same data with fetch_or_add() method will be put on hold, and as soon as the first thread completes the operation, the result will be returned to all threads. Without this feature, a steady stream of requests with less time between them than it takes to complete one request can easily bury a server under an avalanche of threads all wasting resources on the same expensive operation.
14
-
15
- When number of cache entries exceeds the size limit, the least recently accessed entries are replaced with new data. This replacement strategy is controlled by the SynCache::CacheEntry class and can be changed by overriding its replacement_index() method.
16
-
17
- Cache entries are automatically invalidated when their ttl (time to live) is exceeded. Entries can be explicitly invalidated by flush() method. The method can use === operator to compare cache keys against flush base (so that base can be e.g. a Regexp), and invalidates all entries when invoked without the base parameter.
18
-
19
- The flush_delay initialization option allows to limit cache's flush rate. When this option is set, SynCache will make sure that at least this many seconds (it can also be a fraction) pass between two flushes. When extra flushes are requested, invalidation of flushed entries is postponed until earliest time when next flush is allowed.
20
- }
21
- gem.email = "angdraug@debian.org"
22
- gem.homepage = "http://github.com/czarneckid/syncache"
23
- gem.authors = ["Dmitry Borodaenko", "David Czarnecki"]
24
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
25
- end
26
- Jeweler::GemcutterTasks.new
27
- rescue LoadError
28
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
29
- end
30
-
31
- require 'rake/testtask'
32
- Rake::TestTask.new(:test) do |test|
33
- test.libs << 'lib' << 'test'
34
- test.pattern = 'test/**/test_*.rb'
35
- test.verbose = true
36
- end
37
-
38
- begin
39
- require 'rcov/rcovtask'
40
- Rcov::RcovTask.new do |test|
41
- test.libs << 'test'
42
- test.pattern = 'test/**/test_*.rb'
43
- test.verbose = true
44
- end
45
- rescue LoadError
46
- task :rcov do
47
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
48
- end
49
- end
50
-
51
- task :test => :check_dependencies
52
-
53
- task :default => :test
54
-
55
- require 'rake/rdoctask'
56
- Rake::RDocTask.new do |rdoc|
57
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
58
-
59
- rdoc.rdoc_dir = 'rdoc'
60
- rdoc.title = "syncache #{version}"
61
- rdoc.rdoc_files.include('README*')
62
- rdoc.rdoc_files.include('lib/**/*.rb')
63
- end
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 1.0.0
@@ -1,36 +0,0 @@
1
- # Monkey patch for standard sync.rb (see bug #11680 on RubyForge).
2
-
3
- if RUBY_VERSION < "1.8.7" or (RUBY_VERSION == "1.8.7" and RUBY_PATCHLEVEL < 173)
4
-
5
- module Sync_m
6
- class Err < StandardError
7
- def Err.Fail(*opt)
8
- Thread.critical = false
9
- fail self, sprintf(self::Message, *opt)
10
- end
11
- end
12
-
13
- def sync_try_lock(mode = EX)
14
- return unlock if mode == UN
15
-
16
- Thread.critical = true
17
- ret = sync_try_lock_sub(mode)
18
- Thread.critical = false
19
- ret
20
- end
21
- end
22
-
23
- elsif RUBY_VERSION == "1.9.0"
24
-
25
- module Sync_m
26
- def sync_try_lock(mode = EX)
27
- return unlock if mode == UN
28
- ret = nil
29
- @sync_mutex.synchronize do
30
- ret = sync_try_lock_sub(mode)
31
- end
32
- ret
33
- end
34
- end
35
-
36
- end
data/test/helper.rb DELETED
@@ -1,9 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
-
4
- $LOAD_PATH.unshift(File.dirname(__FILE__))
5
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
- require 'syncache'
7
-
8
- class Test::Unit::TestCase
9
- end