cache_guard 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c9c48a204891eb04bb84c52347b5025352f0f41e
4
+ data.tar.gz: 0f90e08c1138244ca18129db5850288a1aab33be
5
+ SHA512:
6
+ metadata.gz: bc8d26739c8394c4892b964473002ad35606ea025324909c2d43f4a3b8125ea08e099afb7f2df3b4ce559ac57b54ce4b14e53b22da9deec798cd25682b8d8b79
7
+ data.tar.gz: fbc853045045d2b9b4ffb870e908155c0cc6655904e86e651b1c2fec3eaeaa9416f31199d44842b09e74f95437e9c3a62b192c5b3deeae3473d326358bb7295c
@@ -0,0 +1,40 @@
1
+ class CacheGuard
2
+ class AcquireError < RuntimeError
3
+ end
4
+
5
+ def initialize(name, options = {})
6
+ @name = name
7
+ @default_value = options[:default_value] || 1
8
+ @expires_in = options[:expires_in] || 120
9
+ @cache_store = options[:cache_store] || Rails.store
10
+ end
11
+
12
+ def guard
13
+ raise AcquireError, "Unable to acquire guard for: #{@name}" unless acquire
14
+
15
+ begin
16
+ yield
17
+ ensure
18
+ release
19
+ end
20
+ end
21
+
22
+ def self.guard(name, options = {}, &block)
23
+ new(name, options).guard(&block)
24
+ end
25
+
26
+ private
27
+
28
+ def acquire
29
+ # The FileStore increment operation returns nil if the cache key doesn't exist. Since the FileStore strategy
30
+ # should be only used in development environment we can allow all guards to pass.
31
+ # http://api.rubyonrails.org/classes/ActiveSupport/Cache/FileStore.html#method-i-increment
32
+ # http://www.rubydoc.info/github/mperham/dalli/ActiveSupport/Cache/DalliStore#increment-instance_method
33
+ value = @cache_store.increment(@name, @default_value, :expires_in => @expires_in)
34
+ value.nil? || value == @default_value ? true : false
35
+ end
36
+
37
+ def release
38
+ @cache_store.delete(@name)
39
+ end
40
+ end
@@ -0,0 +1,57 @@
1
+ require "spec_helper"
2
+ require "cache_guard"
3
+
4
+ describe CacheGuard do
5
+ describe "#guard" do
6
+ let(:cache_store){ double("Cache", :delete => true) }
7
+ subject{ described_class.new("guard", :cache_store => cache_store) }
8
+
9
+ context "when able to acquire guard" do
10
+ before do
11
+ allow(cache_store).to receive(:increment).and_return(1)
12
+ end
13
+
14
+ it "executes the given block" do
15
+ expect{ |probe| subject.guard(&probe) }.to yield_control
16
+ end
17
+
18
+ it "releases on success" do
19
+ subject.guard{ true }
20
+ expect(cache_store).to have_received(:delete)
21
+ end
22
+
23
+ it "releases on exception" do
24
+ subject.guard{ raise } rescue nil
25
+ expect(cache_store).to have_received(:delete)
26
+ end
27
+ end
28
+
29
+ context "when unable to acquire guard" do
30
+ before do
31
+ allow(cache_store).to receive(:increment).and_return(2)
32
+ end
33
+
34
+ it "raises an CacheGuard::AcquireError" do
35
+ expect{ subject.guard{ true } }.to raise_error(CacheGuard::AcquireError)
36
+ end
37
+
38
+ it "doesn't release" do
39
+ subject.guard{ true } rescue nil
40
+ expect(cache_store).to_not have_received(:delete)
41
+ end
42
+ end
43
+ end
44
+
45
+ describe ".guard" do
46
+ subject{ double("guard") }
47
+
48
+ before do
49
+ allow(subject).to receive(:guard).and_yield
50
+ allow(described_class).to receive(:new).with("static", :expires_in => 100).and_return(subject)
51
+ end
52
+
53
+ it "creates a new instance and calls guard with the given block" do
54
+ expect{ |probe| described_class.guard("static", { :expires_in => 100 }, &probe) }.to yield_control
55
+ end
56
+ end
57
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cache_guard
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Duarte Henriques
8
+ - Miguel Teixeira
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-01-13 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '3.4'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '3.4'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rubocop
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: 0.35.1
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: 0.35.1
42
+ description:
43
+ email:
44
+ - duarte.henriques@seedrs.com
45
+ - miguel.teixeira@seedrs.com
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - lib/cache_guard.rb
51
+ - spec/lib/cache_guard_spec.rb
52
+ homepage: http://rubygems.org/gems/cache_guard
53
+ licenses:
54
+ - MIT
55
+ metadata: {}
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubyforge_project:
72
+ rubygems_version: 2.4.8
73
+ signing_key:
74
+ specification_version: 4
75
+ summary: Allows you to protect the execution of a block against concurrency.
76
+ test_files:
77
+ - spec/lib/cache_guard_spec.rb