decoratable 0.0.2 → 0.0.3

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
  SHA1:
3
- metadata.gz: ec20dff74a6642c85271dcb977529bcd33ca8174
4
- data.tar.gz: 9ff3c561a008fff52d078a61ec2ab68630756580
3
+ metadata.gz: 0a1094f3963b004b9afe1f443996e7ef907dcccc
4
+ data.tar.gz: b9d42a93abae4298497a8f43ae39c08e75029154
5
5
  SHA512:
6
- metadata.gz: c940d91c425fd100b43d850ae9e78522ae385a5dc9a52bd321b73c82b8f2f8411e6f4a53597699c657d4a5647d359cf15e30c70abc7198161494f74eeee5d65a
7
- data.tar.gz: 6ef5795b503abba017d278c6bfdcd52c3d04d1929d99a7901829d0f09b14ac10e6db41c87188de9cf4d24d41c19e1b01e6ae3d123986948478bc5445596acba2
6
+ metadata.gz: 76b7cd80a644f31d40fa645c5ac6887f09b9502c9a3240ef140fce3528c703f03b6336ea101afe5c377e40b1cdcc2c48b3c8324bd1913e9be47457a45a509a97
7
+ data.tar.gz: 9e21a985440a6faee8da8a9c24d2607b7c64b501d785a99da864e8c8a76b8a35c2681e4bc2055f9206b24050790c9333f2542a4009191967bbd425ecffed9db9
data/.travis.yml CHANGED
@@ -1,8 +1,10 @@
1
1
  language: ruby
2
+ before_install: gem install bundler
2
3
  rvm:
3
- - 2.0.0
4
- - 2.1.6
5
- - 2.2.2
4
+ - 2.1.10
5
+ - 2.2.6
6
+ - 2.3.3
7
+ - 2.4.0
6
8
  - ruby-head
7
9
  - jruby-head
8
10
  before_install:
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.2"
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
- def retryable(tries = 1, options = { on: [RuntimeError] } )
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 *options[:on]
12
- attempts += 1
13
- attempts > tries ? raise : retry
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
+
@@ -142,7 +142,7 @@ describe Decoratable do
142
142
 
143
143
  def mock_logger
144
144
  logger = Minitest::Mock.new
145
- logger.expect(:info, nil, [/took \d+\.\d+s to run/])
145
+ logger.expect(:info, nil, [/took \d+(\.\d+)?s to run/])
146
146
  logger
147
147
  end
148
148
  end
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.2
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: 2016-11-26 00:00:00.000000000 Z
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
- - ".travis.yml"
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.5.1
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