decoratable 0.0.2 → 0.0.3
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/.travis.yml +5 -3
- data/README.rdoc +1 -0
- data/decoratable.gemspec +1 -1
- data/lib/decoratable/retryable.rb +15 -4
- data/lib/decoratable/synchronizable.rb +18 -0
- data/test/decoratable/retryable_test.rb +17 -0
- data/test/decoratable/synchronizable_test.rb +36 -0
- data/test/decoratable_test.rb +1 -1
- metadata +15 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a1094f3963b004b9afe1f443996e7ef907dcccc
|
4
|
+
data.tar.gz: b9d42a93abae4298497a8f43ae39c08e75029154
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76b7cd80a644f31d40fa645c5ac6887f09b9502c9a3240ef140fce3528c703f03b6336ea101afe5c377e40b1cdcc2c48b3c8324bd1913e9be47457a45a509a97
|
7
|
+
data.tar.gz: 9e21a985440a6faee8da8a9c24d2607b7c64b501d785a99da864e8c8a76b8a35c2681e4bc2055f9206b24050790c9333f2542a4009191967bbd425ecffed9db9
|
data/.travis.yml
CHANGED
data/README.rdoc
CHANGED
@@ -96,5 +96,6 @@ Decoratable provides a handful of decorations as part of the gem:
|
|
96
96
|
* require "decoratable/memoizable": automatically memoize the return value of a method
|
97
97
|
* require "decoratable/pryable": open a Pry debug console (i.e. binding.pry) if an error is raised
|
98
98
|
* require "decoratable/retryable": automatically retry a number of times when a specified exception is raised
|
99
|
+
* require "decoratable/synchronizable": only allow a method to be called once at a time
|
99
100
|
|
100
101
|
More to be added as time goes on.
|
data/decoratable.gemspec
CHANGED
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |spec|
|
5
5
|
spec.name = "decoratable"
|
6
|
-
spec.version = "0.0.
|
6
|
+
spec.version = "0.0.3"
|
7
7
|
spec.authors = ["ecin"]
|
8
8
|
spec.email = ["ecin@copypastel.com"]
|
9
9
|
spec.description = "Decorate your methods."
|
@@ -3,14 +3,25 @@ require "decoratable"
|
|
3
3
|
module Retryable
|
4
4
|
extend Decoratable
|
5
5
|
|
6
|
-
|
6
|
+
NO_BACKOFF = proc { 0 }
|
7
|
+
LINEAR_BACKOFF = proc { |n| n + 1 }
|
8
|
+
EXPONENTIAL_BACKOFF = proc { |n| 2**n }
|
9
|
+
|
10
|
+
def retryable(tries = 1, on: [RuntimeError], backoff: NO_BACKOFF)
|
7
11
|
attempts = 0
|
12
|
+
on = Array(on)
|
8
13
|
|
9
14
|
begin
|
10
15
|
yield
|
11
|
-
rescue *
|
12
|
-
|
13
|
-
attempts
|
16
|
+
rescue *on
|
17
|
+
|
18
|
+
if attempts >= tries
|
19
|
+
raise
|
20
|
+
else
|
21
|
+
sleep backoff.call(attempts)
|
22
|
+
attempts += 1
|
23
|
+
retry
|
24
|
+
end
|
14
25
|
end
|
15
26
|
end
|
16
27
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "decoratable"
|
2
|
+
|
3
|
+
module Synchronizable
|
4
|
+
extend Decoratable
|
5
|
+
|
6
|
+
@@locks = {}
|
7
|
+
@@locks_lock = Mutex.new
|
8
|
+
|
9
|
+
def synchronizable(lock: Mutex.new)
|
10
|
+
@@locks_lock.synchronize do
|
11
|
+
lock = @@locks[__decorated_method__.source_location] ||= lock
|
12
|
+
end
|
13
|
+
|
14
|
+
lock.synchronize do
|
15
|
+
yield
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -21,6 +21,18 @@ describe Retryable do
|
|
21
21
|
ensure
|
22
22
|
@count += 1
|
23
23
|
end
|
24
|
+
|
25
|
+
retryable(3, on: RuntimeError, backoff: Retryable::LINEAR_BACKOFF)
|
26
|
+
def call_with_backoff
|
27
|
+
raise RuntimeError
|
28
|
+
end
|
29
|
+
|
30
|
+
# Stub sleep
|
31
|
+
def sleep(seconds = nil)
|
32
|
+
@calls ||= []
|
33
|
+
|
34
|
+
seconds.nil? ? @calls : @calls.push(seconds)
|
35
|
+
end
|
24
36
|
end
|
25
37
|
|
26
38
|
@object = klass.new
|
@@ -30,4 +42,9 @@ describe Retryable do
|
|
30
42
|
proc { @object.call }.must_raise NoMethodError
|
31
43
|
end
|
32
44
|
|
45
|
+
it "supports custom backoff algorithms" do
|
46
|
+
proc { @object.call_with_backoff }.must_raise RuntimeError
|
47
|
+
@object.sleep.must_equal [1, 2, 3]
|
48
|
+
end
|
49
|
+
|
33
50
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
require "decoratable/synchronizable"
|
4
|
+
|
5
|
+
describe Synchronizable do
|
6
|
+
before do
|
7
|
+
klass = Class.new do
|
8
|
+
extend Synchronizable
|
9
|
+
|
10
|
+
attr_reader :count
|
11
|
+
|
12
|
+
synchronizable
|
13
|
+
def increment
|
14
|
+
if @count.nil?
|
15
|
+
sleep 1
|
16
|
+
@count = 0
|
17
|
+
else
|
18
|
+
@count += 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
@object = klass.new
|
24
|
+
end
|
25
|
+
|
26
|
+
it "runs the method once at a time" do
|
27
|
+
threads = 2.times.map { Thread.new { @object.increment } }
|
28
|
+
threads.each(&:join)
|
29
|
+
|
30
|
+
# If calls to increment aren't synchronized,
|
31
|
+
# @object.count would be equal to 0
|
32
|
+
@object.count.must_equal 1
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
data/test/decoratable_test.rb
CHANGED
metadata
CHANGED
@@ -1,55 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: decoratable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ecin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-05-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: pry
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 10.0.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 10.0.0
|
55
55
|
description: Decorate your methods.
|
@@ -59,7 +59,7 @@ executables: []
|
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
-
-
|
62
|
+
- .travis.yml
|
63
63
|
- Gemfile
|
64
64
|
- README.rdoc
|
65
65
|
- Rakefile
|
@@ -72,12 +72,14 @@ files:
|
|
72
72
|
- lib/decoratable/memoizable.rb
|
73
73
|
- lib/decoratable/pryable.rb
|
74
74
|
- lib/decoratable/retryable.rb
|
75
|
+
- lib/decoratable/synchronizable.rb
|
75
76
|
- test/decoratable/countable_test.rb
|
76
77
|
- test/decoratable/deprecatable_test.rb
|
77
78
|
- test/decoratable/hintable_test.rb
|
78
79
|
- test/decoratable/memoizable_test.rb
|
79
80
|
- test/decoratable/pryable_test.rb
|
80
81
|
- test/decoratable/retryable_test.rb
|
82
|
+
- test/decoratable/synchronizable_test.rb
|
81
83
|
- test/decoratable_test.rb
|
82
84
|
- test/test_helper.rb
|
83
85
|
homepage: https://github.com/ecin/decoratable
|
@@ -90,17 +92,17 @@ require_paths:
|
|
90
92
|
- lib
|
91
93
|
required_ruby_version: !ruby/object:Gem::Requirement
|
92
94
|
requirements:
|
93
|
-
- -
|
95
|
+
- - '>='
|
94
96
|
- !ruby/object:Gem::Version
|
95
97
|
version: '0'
|
96
98
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
99
|
requirements:
|
98
|
-
- -
|
100
|
+
- - '>='
|
99
101
|
- !ruby/object:Gem::Version
|
100
102
|
version: '0'
|
101
103
|
requirements: []
|
102
104
|
rubyforge_project:
|
103
|
-
rubygems_version: 2.
|
105
|
+
rubygems_version: 2.0.14.1
|
104
106
|
signing_key:
|
105
107
|
specification_version: 4
|
106
108
|
summary: Easily define decorations for your methods. Put a bow on it.
|
@@ -111,5 +113,6 @@ test_files:
|
|
111
113
|
- test/decoratable/memoizable_test.rb
|
112
114
|
- test/decoratable/pryable_test.rb
|
113
115
|
- test/decoratable/retryable_test.rb
|
116
|
+
- test/decoratable/synchronizable_test.rb
|
114
117
|
- test/decoratable_test.rb
|
115
118
|
- test/test_helper.rb
|