retryable_record 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -2,6 +2,7 @@ language: ruby
2
2
  rvm:
3
3
  - ree
4
4
  - 1.9.3
5
+ - 2.0.0
5
6
  - jruby-18mode
6
7
  - jruby-19mode
7
8
  - rbx-18mode
data/README.rdoc CHANGED
@@ -2,14 +2,37 @@
2
2
 
3
3
  Retries an operation on an ActiveRecord until no StaleObjectError is being raised.
4
4
 
5
+ {<img src="https://secure.travis-ci.org/neopoly/retryable_record.png?branch=master" alt="Build Status" />}[http://travis-ci.org/neopoly/retryable_record] {<img src="https://badge.fury.io/rb/retryable_record.png" alt="Gem Version" />}[http://badge.fury.io/rb/retryable_record] {<img src="https://codeclimate.com/github/neopoly/retryable_record.png" />}[https://codeclimate.com/github/neopoly/retryable_record]
6
+
5
7
  Gem[https://rubygems.org/gems/retryable_record] |
6
8
  Source[http://github.com/neopoly/retryable_record] |
7
- RDoc[http://rdoc.info/projects/neopoly/retryable_record] |
8
- {<img src="https://secure.travis-ci.org/neopoly/retryable_record.png?branch=master" alt="Build Status" />}[http://travis-ci.org/neopoly/retryable_record]
9
+ Documentation[http://rdoc.info/github/neopoly/retryable_record/master/frames]
9
10
 
10
11
 
11
12
  == Usage
12
13
 
14
+ You can use +retryable_record+ in 3 different ways:
15
+
16
+ === Module function
17
+
18
+ require 'retryable_record'
19
+
20
+ RetryableRecord.retry(user) do
21
+ user.username = "foo"
22
+ user.save!
23
+ end
24
+
25
+ === Kernel import
26
+
27
+ require 'retryable_record/import'
28
+
29
+ RetryableRecord(user) do
30
+ user.username = "foo"
31
+ user.save!
32
+ end
33
+
34
+ === Module inclusion
35
+
13
36
  require 'retryable_record'
14
37
 
15
38
  class User < ActiveRecord::Base
@@ -23,12 +46,28 @@ RDoc[http://rdoc.info/projects/neopoly/retryable_record] |
23
46
  user.save!
24
47
  end
25
48
 
49
+ == Optimistic locking (lock_version column)
50
+
51
+ ActiveRecord migration needs to support optimistic locking. See http://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html
52
+
53
+ class CreateUsers < ActiveRecord::Migration
54
+ def change
55
+ create_table :users do |t|
56
+ t.string :name
57
+ t.integer :lock_version
58
+
59
+ t.timestamps
60
+ end
61
+ end
62
+ end
63
+
64
+
26
65
  == Credits
27
66
 
28
67
  Inspired by
29
- * http://vision-media.ca/resources/ruby/better-ruby-retryable-method
30
68
  * http://blog.codefront.net/2008/01/14/retrying-code-blocks-in-ruby-on-exceptions-whatever/
31
- * http://github.com/carlo/retryable
69
+ * http://github.com/nfedyashev/retryable
70
+ * http://vision-media.ca/resources/ruby/better-ruby-retryable-method (broken)
32
71
 
33
72
  == TODO
34
73
 
@@ -0,0 +1,19 @@
1
+ require 'retryable_record'
2
+
3
+ module Kernel
4
+ # Retryable operations on an ActiveRecord +record+.
5
+ #
6
+ # == Example
7
+ #
8
+ # require 'retryable_record/import'
9
+ #
10
+ # RetryableRecord(user) do
11
+ # user.username = "foo"
12
+ # user.save!
13
+ # end
14
+ #
15
+ # See RetryableRecord#retry
16
+ def RetryableRecord(record, &block)
17
+ RetryableRecord.retry(record, &block)
18
+ end
19
+ end
@@ -1,3 +1,3 @@
1
1
  module RetryableRecord
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -3,7 +3,7 @@ require 'active_record/base'
3
3
 
4
4
  # Retries an operation on an ActiveRecord until no StaleObjectError is being raised.
5
5
  #
6
- # @example
6
+ # == Example
7
7
  #
8
8
  # class User < ActiveRecord::Base
9
9
  # include RetryableRecord
@@ -16,12 +16,26 @@ require 'active_record/base'
16
16
  # user.save!
17
17
  # end
18
18
  #
19
- # @yield Operation that should be retried on failure ActiveRecord::StaleObjectError.
20
19
  module RetryableRecord
21
- def retryable(&block)
20
+ # Retryable operations on an ActiveRecord +record+.
21
+ #
22
+ # == Example
23
+ #
24
+ # RetryableRecord.retry(user) do
25
+ # user.username = "foo"
26
+ # user.save!
27
+ # end
28
+ #
29
+ def retry(record)
22
30
  yield
23
31
  rescue ActiveRecord::StaleObjectError
24
- reload
32
+ record.reload
25
33
  retry
26
34
  end
35
+ module_function :retry
36
+
37
+ # Retries operations on an ActiveRecord.
38
+ def retryable(&block)
39
+ RetryableRecord.retry(self, &block)
40
+ end
27
41
  end
@@ -18,5 +18,6 @@ Gem::Specification.new do |gem|
18
18
  gem.add_runtime_dependency 'activerecord', '>= 3'
19
19
 
20
20
  gem.add_development_dependency 'rake'
21
+ gem.add_development_dependency 'rdoc'
21
22
  gem.add_development_dependency 'minitest', '~> 3.2.0'
22
23
  end
data/test/helper.rb CHANGED
@@ -6,12 +6,6 @@ require 'minitest/autorun'
6
6
  require 'retryable_record'
7
7
 
8
8
  class Spec < MiniTest::Spec
9
- class << self
10
- alias :context :describe
11
- alias :test :it
12
- alias :setup :before
13
- alias :teardown :after
14
- end
15
9
  end
16
10
 
17
11
  class FakeRecord
@@ -0,0 +1,23 @@
1
+ require 'helper'
2
+ require 'retryable_record/import'
3
+
4
+ class RetryableRecordImportTest < Spec
5
+ let(:retries) { 0 }
6
+ let(:record) { FakeRecord.new(retries) }
7
+
8
+ describe :RetryableRecord do
9
+ before do
10
+ RetryableRecord(record) do
11
+ record.concurrent_modification!
12
+ record.save!
13
+ end
14
+ end
15
+
16
+ let(:retries) { 0 }
17
+
18
+ it "saves and does not retry" do
19
+ assert_equal 0, record.counter[:reload]
20
+ assert_equal 1, record.counter[:save]
21
+ end
22
+ end
23
+ end
@@ -4,33 +4,33 @@ class RetryableRecordTest < Spec
4
4
  let(:retries) { 0 }
5
5
  let(:record) { FakeRecord.new(retries) }
6
6
 
7
- setup do
8
- record.retryable do
9
- record.concurrent_modification!
10
- record.save!
7
+ describe :retry do
8
+ before do
9
+ RetryableRecord.retry(record) do
10
+ record.concurrent_modification!
11
+ record.save!
12
+ end
11
13
  end
12
- end
13
14
 
14
- context :retryable do
15
- context "without retry" do
15
+ describe "without retry" do
16
16
  let(:retries) { 0 }
17
17
 
18
- test "saves and does not retry" do
18
+ it "saves and does not retry" do
19
19
  assert_equal 0, record.counter[:reload]
20
20
  assert_equal 1, record.counter[:save]
21
21
  end
22
22
  end
23
23
 
24
- context "with retry once" do
24
+ describe "with retry once" do
25
25
  let(:retries) { 5 }
26
26
 
27
- test "saves and reloads 5 times" do
27
+ it "saves and reloads 5 times" do
28
28
  assert_equal 5, record.counter[:reload]
29
29
  assert_equal 1, record.counter[:save]
30
30
  end
31
31
  end
32
32
 
33
- test "does not rescue other errors" do
33
+ it "does not rescue other errors" do
34
34
  assert_raises RuntimeError do
35
35
  record.retryable do
36
36
  raise "foo"
@@ -41,4 +41,20 @@ class RetryableRecordTest < Spec
41
41
  assert_equal 1, record.counter[:save]
42
42
  end
43
43
  end
44
+
45
+ describe :retryable do
46
+ before do
47
+ record.retryable do
48
+ record.concurrent_modification!
49
+ record.save!
50
+ end
51
+ end
52
+
53
+ let(:retries) { 0 }
54
+
55
+ it "saves and does not retry" do
56
+ assert_equal 0, record.counter[:reload]
57
+ assert_equal 1, record.counter[:save]
58
+ end
59
+ end
44
60
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: retryable_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-02 00:00:00.000000000 Z
12
+ date: 2013-05-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -43,6 +43,22 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rdoc
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
46
62
  - !ruby/object:Gem::Dependency
47
63
  name: minitest
48
64
  requirement: !ruby/object:Gem::Requirement
@@ -77,10 +93,11 @@ files:
77
93
  - Rakefile
78
94
  - VERSION
79
95
  - lib/retryable_record.rb
96
+ - lib/retryable_record/import.rb
80
97
  - lib/retryable_record/version.rb
81
98
  - retryable_record.gemspec
82
- - test.watchr
83
99
  - test/helper.rb
100
+ - test/retryable_record_import_test.rb
84
101
  - test/retryable_record_test.rb
85
102
  homepage: https://github.com/neopoly/retryable_record
86
103
  licenses: []
@@ -94,19 +111,26 @@ required_ruby_version: !ruby/object:Gem::Requirement
94
111
  - - ! '>='
95
112
  - !ruby/object:Gem::Version
96
113
  version: '0'
114
+ segments:
115
+ - 0
116
+ hash: -864916261665633026
97
117
  required_rubygems_version: !ruby/object:Gem::Requirement
98
118
  none: false
99
119
  requirements:
100
120
  - - ! '>='
101
121
  - !ruby/object:Gem::Version
102
122
  version: '0'
123
+ segments:
124
+ - 0
125
+ hash: -864916261665633026
103
126
  requirements: []
104
127
  rubyforge_project:
105
- rubygems_version: 1.8.24
128
+ rubygems_version: 1.8.25
106
129
  signing_key:
107
130
  specification_version: 3
108
131
  summary: Retries an operation on an ActiveRecord until no StaleObjectError is being
109
132
  raised.
110
133
  test_files:
111
134
  - test/helper.rb
135
+ - test/retryable_record_import_test.rb
112
136
  - test/retryable_record_test.rb
data/test.watchr DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env watchr
2
-
3
- begin
4
- require File.join(ENV["HOME"], ".watchr.test.rb")
5
- rescue LoadError
6
- warn "Unable to load #{File.join(ENV["HOME"], ".watchr.test.rb")}"
7
- warn "You might try this: http://gist.github.com/raw/273574/8804dff44b104e9b8706826dc8882ed985b4fd13/.watchr.test.rb"
8
- exit
9
- end
10
-
11
- run_tests
12
-
13
- watch('test/.*_test\.rb') { |md| run md[0] }
14
- watch('lib/(.*)\.rb') { |md| run "test/#{underscore(md[1])}_test.rb" }
15
- watch('test/teststrap.rb') { run_tests }