zache 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8ad9aee02e0592400be73acb02cdf8878c314950df90fce1632ea00e7d07d396
4
- data.tar.gz: 802eba8bf8ad6e027b17d85eb296957b0255fde72e9340713bad5b0b96e4dd67
3
+ metadata.gz: d27ca46de41af5519d5ad841403ce28c1527e8c7a2ec2243cb32c4c4924a684c
4
+ data.tar.gz: 0eab718467f7ee55909fc3d0aa7c4b6ac11881f38c7d6f2deaaa01cc231a259e
5
5
  SHA512:
6
- metadata.gz: c756d6ba076c41371f3c47d1d2f825f06876ea9dea1d39a86f1d7f5f6b93a87d077427af2726e4dc211248e416b02dba26a130a54b1a40e74eeb8f3e64b982bc
7
- data.tar.gz: af8e41d5048f8afa5275362d3e23da9b9276c6277f7f0db33d0353e40bac2e4223806da97f612621b5b587e9f8c964aa737310696a76b9829f242ec543b6fae1
6
+ metadata.gz: d05683cac3f782074b17f4fb0a0a26e025f6f5ed4c887c338f1f940079cc122601c02f81ed035789ca894ed93aa046dda3522f6f96a712c7f5c800192d6edcb4
7
+ data.tar.gz: b3b691d80b84f24c5542c0e33932fa541624aefa0f8ee216aef444788cafba7d7dbabf05694e83c3f340b64a18dd67048bad25edcd4c557c1fcdb7119630f724
data/.rubocop.yml CHANGED
@@ -2,6 +2,9 @@ AllCops:
2
2
  DisplayCopNames: true
3
3
  TargetRubyVersion: 2.3.3
4
4
 
5
+ Metrics/ClassLength:
6
+ Exclude:
7
+ - 'test/*.rb'
5
8
  Layout/MultilineMethodCallIndentation:
6
9
  Enabled: false
7
10
  Metrics/AbcSize:
data/README.md CHANGED
@@ -3,8 +3,10 @@
3
3
  [![We recommend RubyMine](http://www.elegantobjects.org/rubymine.svg)](https://www.jetbrains.com/ruby/)
4
4
 
5
5
  [![Build Status](https://travis-ci.org/yegor256/zache.svg)](https://travis-ci.org/yegor256/zache)
6
+ [![Build status](https://ci.appveyor.com/api/projects/status/7eday736u9phnjiy?svg=true)](https://ci.appveyor.com/project/yegor256/zache)
6
7
  [![Gem Version](https://badge.fury.io/rb/zache.svg)](http://badge.fury.io/rb/zache)
7
8
  [![Maintainability](https://api.codeclimate.com/v1/badges/c136afe340fa94f14696/maintainability)](https://codeclimate.com/github/yegor256/zache/maintainability)
9
+ [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://rubydoc.info/github/yegor256/zache/master/frames)
8
10
 
9
11
  It's a simple Ruby gem for in-memory cache.
10
12
 
data/appveyor.yml ADDED
@@ -0,0 +1,38 @@
1
+ version: '{build}'
2
+ skip_tags: true
3
+ clone_depth: 10
4
+ branches:
5
+ only:
6
+ - master
7
+ except:
8
+ - gh-pages
9
+ os: Windows Server 2012
10
+ environment:
11
+ matrix:
12
+ - ruby_version: "23-x64"
13
+ - ruby_version: "24-x64"
14
+ - ruby_version: "25-x64"
15
+ install:
16
+ - ps: |
17
+ $Env:PATH = "C:\Ruby${Env:ruby_version}\bin;${Env:PATH}"
18
+ if ($Env:ruby_version -match "^23" ) {
19
+ # RubyInstaller; download OpenSSL headers from OpenKnapsack Project
20
+ $Env:openssl_dir = "C:\Ruby${Env:ruby_version}"
21
+ appveyor DownloadFile http://dl.bintray.com/oneclick/OpenKnapsack/x64/openssl-1.0.2j-x64-windows.tar.lzma
22
+ 7z e openssl-1.0.2j-x64-windows.tar.lzma
23
+ 7z x -y -oC:\Ruby${Env:ruby_version} openssl-1.0.2j-x64-windows.tar
24
+ } else {
25
+ # RubyInstaller2; openssl package seems to be installed already
26
+ $Env:openssl_dir = "C:\msys64\mingw64"
27
+ }
28
+ - bundle config --local path vendor/bundle
29
+ - bundle config build.openssl --with-openssl-dir=%openssl_dir%
30
+ - ruby -v
31
+ - bundle -v
32
+ build_script:
33
+ - bundle update
34
+ - bundle install
35
+ test_script:
36
+ - bundle exec rake --quiet
37
+ cache:
38
+ - vendor/bundle
data/lib/zache.rb CHANGED
@@ -22,6 +22,8 @@
22
22
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
23
  # SOFTWARE.
24
24
 
25
+ require 'monitor'
26
+
25
27
  # It is a very simple thread-safe in-memory cache with an ability to expire
26
28
  # keys automatically, when their lifetime is over. Use it like this:
27
29
  #
@@ -44,7 +46,7 @@ class Zache
44
46
  def initialize(sync: true)
45
47
  @hash = {}
46
48
  @sync = sync
47
- @mutex = Mutex.new
49
+ @monitor = Monitor.new
48
50
  end
49
51
 
50
52
  # Gets the value from the cache by the provided key. If the value is not
@@ -52,13 +54,7 @@ class Zache
52
54
  # the block is not given, an exception will be raised.
53
55
  def get(key, lifetime: 60 * 60)
54
56
  raise 'A block is required' unless block_given?
55
- if @sync
56
- @mutex.synchronize do
57
- calc(key, lifetime) { yield }
58
- end
59
- else
60
- calc(key, lifetime) { yield }
61
- end
57
+ synchronized { calc(key, lifetime) { yield } }
62
58
  end
63
59
 
64
60
  # Checks whether the value exists in the cache by the provided key. Returns
@@ -76,27 +72,15 @@ class Zache
76
72
  # Removes the value from the hash, by the provied key. If the key is absent
77
73
  # and the block is provide, the block will be called.
78
74
  def remove(key)
79
- if @sync
80
- @mutex.synchronize do
81
- @hash.delete(key) { yield if block_given? }
82
- end
83
- else
84
- @hash.delete(key) { yield if block_given? }
85
- end
75
+ synchronized { @hash.delete(key) { yield if block_given? } }
76
+ end
77
+
78
+ def remove_all
79
+ synchronized { @hash = {} }
86
80
  end
87
81
 
88
82
  def clean
89
- if @sync
90
- @mutex.synchronize do
91
- @hash.delete_if do |_key, value|
92
- value[:start] < Time.now - value[:lifetime]
93
- end
94
- end
95
- else
96
- @hash.delete_if do |_key, value|
97
- value[:start] < Time.now - value[:lifetime]
98
- end
99
- end
83
+ synchronized { @hash.delete_if { |_key, value| key_expired?(value) } }
100
84
  end
101
85
 
102
86
  private
@@ -114,6 +98,14 @@ class Zache
114
98
  @hash[key][:value]
115
99
  end
116
100
 
101
+ def synchronized
102
+ if @sync
103
+ @monitor.synchronize { yield }
104
+ else
105
+ yield
106
+ end
107
+ end
108
+
117
109
  def key_expired?(key)
118
110
  rec = @hash[key]
119
111
  !rec.nil? && rec[:start] < Time.now - rec[:lifetime]
data/test/test_zache.rb CHANGED
@@ -126,4 +126,39 @@ class ZacheTest < Minitest::Test
126
126
  cache.get(:hey, lifetime: 0) { Random.rand }
127
127
  assert(!cache.exists?(:hey))
128
128
  end
129
+
130
+ def test_remove_all_with_threads
131
+ cache = Zache.new
132
+ Threads.new(10).assert(100) do |i|
133
+ cache.get("hey#{i}".to_sym) { Random.rand }
134
+ assert(cache.exists?("hey#{i}".to_sym) == true)
135
+ cache.remove_all
136
+ end
137
+ 10.times do |i|
138
+ assert(cache.exists?("hey#{i}".to_sym) == false)
139
+ end
140
+ end
141
+
142
+ def test_remove_all_with_sync
143
+ cache = Zache.new
144
+ cache.get(:hey) { Random.rand }
145
+ cache.get(:bye) { Random.rand }
146
+ cache.remove_all
147
+ assert(cache.exists?(:hey) == false)
148
+ assert(cache.exists?(:bye) == false)
149
+ end
150
+
151
+ def test_remove_all_without_sync
152
+ cache = Zache.new(sync: false)
153
+ cache.get(:hey) { Random.rand }
154
+ cache.get(:bye) { Random.rand }
155
+ cache.remove_all
156
+ assert(cache.exists?(:hey) == false)
157
+ assert(cache.exists?(:bye) == false)
158
+ end
159
+
160
+ def test_sync_zache_is_reentrant
161
+ cache = Zache.new
162
+ cache.get(:first) { cache.get(:second) { 1 } }
163
+ end
129
164
  end
data/zache.gemspec CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
31
31
  s.rubygems_version = '2.3.3'
32
32
  s.required_ruby_version = '>=2.3'
33
33
  s.name = 'zache'
34
- s.version = '0.3.0'
34
+ s.version = '0.3.1'
35
35
  s.license = 'MIT'
36
36
  s.summary = 'In-memory Cache'
37
37
  s.description = 'Zero-footprint in-memory thread-safe cache'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zache
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-07 00:00:00.000000000 Z
11
+ date: 2018-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -110,6 +110,7 @@ files:
110
110
  - Gemfile
111
111
  - README.md
112
112
  - Rakefile
113
+ - appveyor.yml
113
114
  - lib/zache.rb
114
115
  - test/test_zache.rb
115
116
  - zache.gemspec