zache 0.3.0 → 0.3.1
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/README.md +2 -0
- data/appveyor.yml +38 -0
- data/lib/zache.rb +18 -26
- data/test/test_zache.rb +35 -0
- data/zache.gemspec +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d27ca46de41af5519d5ad841403ce28c1527e8c7a2ec2243cb32c4c4924a684c
|
4
|
+
data.tar.gz: 0eab718467f7ee55909fc3d0aa7c4b6ac11881f38c7d6f2deaaa01cc231a259e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d05683cac3f782074b17f4fb0a0a26e025f6f5ed4c887c338f1f940079cc122601c02f81ed035789ca894ed93aa046dda3522f6f96a712c7f5c800192d6edcb4
|
7
|
+
data.tar.gz: b3b691d80b84f24c5542c0e33932fa541624aefa0f8ee216aef444788cafba7d7dbabf05694e83c3f340b64a18dd67048bad25edcd4c557c1fcdb7119630f724
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -3,8 +3,10 @@
|
|
3
3
|
[](https://www.jetbrains.com/ruby/)
|
4
4
|
|
5
5
|
[](https://travis-ci.org/yegor256/zache)
|
6
|
+
[](https://ci.appveyor.com/project/yegor256/zache)
|
6
7
|
[](http://badge.fury.io/rb/zache)
|
7
8
|
[](https://codeclimate.com/github/yegor256/zache/maintainability)
|
9
|
+
[](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
|
-
@
|
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
|
-
|
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
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|
-
|
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.
|
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.
|
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-
|
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
|