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 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