attempt 0.3.2 → 0.6.1
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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/{CHANGES → CHANGES.md} +43 -8
- data/Gemfile +8 -0
- data/LICENSE +177 -0
- data/MANIFEST.md +10 -0
- data/README.md +84 -0
- data/Rakefile +26 -29
- data/attempt.gemspec +7 -8
- data/certs/djberg96_pub.pem +22 -17
- data/lib/attempt.rb +41 -30
- data/spec/attempt_spec.rb +67 -0
- metadata +61 -47
- metadata.gz.sig +0 -0
- data/MANIFEST +0 -8
- data/README +0 -67
- data/test/test_attempt.rb +0 -64
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 9f4489fdcd16a1e4fd93187cf684afc4eb42b9d1b35987372ce099b0081ab938
|
|
4
|
+
data.tar.gz: 0d359e069dded75e7e0871c1903f5950275b5f033e22490ea3358c55e8883df0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 61728e4d946893471d103dfa8f2114212bf9438774b6636cff3744186fe0c99f7e48687969abe8627aa48b4cdb0d7203666978ded8bae2b3ba9d4f1e2616d57b
|
|
7
|
+
data.tar.gz: a34ac935d3fde78fed37884e93f9019c015a106c15f741732fedd2184c298eb1233ab23f967dfb85bfa6eaf1bb873d6e208730c20cf59cf40bbf101122f5c1a5
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data.tar.gz.sig
CHANGED
|
Binary file
|
data/{CHANGES → CHANGES.md}
RENAMED
|
@@ -1,21 +1,53 @@
|
|
|
1
|
-
|
|
1
|
+
## 0.6.1 - 20-Oct-2020
|
|
2
|
+
* Switched the README, MANIFEST and CHANGES to markdown format.
|
|
3
|
+
* Fiddling with the .travis.yml file again.
|
|
4
|
+
|
|
5
|
+
## 0.6.0 - 17-Sep-2020
|
|
6
|
+
|
|
7
|
+
* Switched from test-unit to rspec and rewrote the specs.
|
|
8
|
+
|
|
9
|
+
## 0.5.1 - 28-Aug-2020
|
|
10
|
+
|
|
11
|
+
* Added a Gemfile.
|
|
12
|
+
* Updated Rakefile to clean .lock files.
|
|
13
|
+
* Bumped structured_warnings version to 0.4.0 so that it works with Ruby 2.7.
|
|
14
|
+
Thanks go to Alexey Zapriy for the spot.
|
|
15
|
+
|
|
16
|
+
## 0.5.0 - 2-Jun-2020
|
|
17
|
+
|
|
18
|
+
* Switched to Apache-2.0 license, added LICENSE file.
|
|
19
|
+
* Updated cert again.
|
|
20
|
+
|
|
21
|
+
## 0.4.0 - 5-Sep-2017
|
|
22
|
+
|
|
23
|
+
* Switched constructor to use keyword arguments.
|
|
24
|
+
* Replaced Timeout with SafeTimeout and added the safe_timeout dependency.
|
|
25
|
+
* The :log option now accepts either an IO or Logger object.
|
|
26
|
+
* Updated cert.
|
|
27
|
+
|
|
28
|
+
## 0.3.2 - 4-Apr-2017
|
|
29
|
+
|
|
2
30
|
* Fix metadata key names.
|
|
3
31
|
|
|
4
|
-
|
|
32
|
+
## 0.3.1 - 4-Apr-2017
|
|
33
|
+
|
|
5
34
|
* Added some metadata to the gemspec.
|
|
6
35
|
|
|
7
|
-
|
|
36
|
+
## 0.3.0 - 27-Mar-2017
|
|
37
|
+
|
|
8
38
|
* The structured_warnings gem requirement was updated to 0.3.0 or later. This
|
|
9
39
|
is necessary if you are using Ruby 2.4 or later.
|
|
10
40
|
* The VERSION string is now frozen.
|
|
11
41
|
* Updated the certs file.
|
|
12
42
|
|
|
13
|
-
|
|
43
|
+
## 0.2.1 - 13-Dec-2015
|
|
44
|
+
|
|
14
45
|
* This gem is now signed.
|
|
15
46
|
* Updates to the Rakefile and gemspec.
|
|
16
47
|
* Added a caveat regarding the timeout module to the README.
|
|
17
48
|
|
|
18
|
-
|
|
49
|
+
## 0.2.0 - 26-Sep-2009
|
|
50
|
+
|
|
19
51
|
* Now requires and uses the structured_warnings gem. If a block of code fails
|
|
20
52
|
prior to reaching the maximum number of tries, and warnings are on, then
|
|
21
53
|
an Attempt::Warning is raised.
|
|
@@ -23,16 +55,19 @@
|
|
|
23
55
|
* Refactored the attempt.gemspec file a bit.
|
|
24
56
|
* Added the 'gem' task to the Rakefile.
|
|
25
57
|
|
|
26
|
-
|
|
58
|
+
## 0.1.2 - 1-Aug-2009
|
|
59
|
+
|
|
27
60
|
* License changed to Artistic 2.0.
|
|
28
61
|
* Added test-unit as a development dependency.
|
|
29
62
|
* Test file renamed to more closely follow Ruby style.
|
|
30
63
|
* Gemspec updates, including addition of license.
|
|
31
64
|
|
|
32
|
-
|
|
65
|
+
## 0.1.1 - 31-Jul-2007
|
|
66
|
+
|
|
33
67
|
* Added a Rakefile with tasks for testing and installation.
|
|
34
68
|
* Removed the install.rb file, since installation is now handled by the Rakefile.
|
|
35
69
|
* Some minor doc updates.
|
|
36
70
|
|
|
37
|
-
|
|
71
|
+
## 0.1.0 - 9-Jun-2006
|
|
72
|
+
|
|
38
73
|
* Initial commit
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
data/MANIFEST.md
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
## Description
|
|
2
|
+
|
|
3
|
+
A thin wrapper for begin + rescue + sleep + retry.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
gem install attempt
|
|
8
|
+
|
|
9
|
+
## Synopsis
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
require 'attempt'
|
|
13
|
+
|
|
14
|
+
# Attempt to ftp to some host, trying 3 times with 30 seconds between
|
|
15
|
+
# attempts before finally raising an error.
|
|
16
|
+
|
|
17
|
+
attempt(tries: 3, interval: 30){
|
|
18
|
+
Net::FTP.open(host, user, passwd){ ... }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
# Or, do things the long way...
|
|
22
|
+
code = Attempt.new do |a|
|
|
23
|
+
a.tries = 3
|
|
24
|
+
a.interval = 30
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
code.attempt{
|
|
28
|
+
Net::FTP.open(host, user, passwd){ ... }
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Known Bugs
|
|
33
|
+
|
|
34
|
+
None that I'm aware of. If you find any bugs, please log them on the project page at:
|
|
35
|
+
|
|
36
|
+
https://github.com/djberg96/attempt
|
|
37
|
+
|
|
38
|
+
## Caveats
|
|
39
|
+
|
|
40
|
+
Use with caution. Specifically, make sure you aren't inadvertantly
|
|
41
|
+
wrapping code that already performs sleep + retry. Otherwise, you'll
|
|
42
|
+
end up with a series of nested retry's that could take much longer to
|
|
43
|
+
work than you expect.
|
|
44
|
+
|
|
45
|
+
Also, this library uses the timeout library internally, which has some
|
|
46
|
+
known issues. See Future Plans, below.
|
|
47
|
+
|
|
48
|
+
As of version 0.3.0, this library requires structured_warnings 0.3.0 or
|
|
49
|
+
later. This is necessary because of changes in Ruby 2.4.
|
|
50
|
+
|
|
51
|
+
Update: I've switched from the timeout library in the standard library to
|
|
52
|
+
the safe_timeout library which should improve things. In addition, the
|
|
53
|
+
structured_warnings library requirement is now 0.4.0 or later in order to
|
|
54
|
+
work with Ruby 2.7.
|
|
55
|
+
|
|
56
|
+
## Future Plans
|
|
57
|
+
|
|
58
|
+
Add the ability to set an absolute maximum number of seconds to prevent
|
|
59
|
+
nested sleep/retry from delaying attempts longer than expected.
|
|
60
|
+
|
|
61
|
+
Replace the timeout library with a self selecting pipe if possible.
|
|
62
|
+
|
|
63
|
+
## Acknowledgements
|
|
64
|
+
|
|
65
|
+
This library is partially based on Mark Fowler's 'Attempt' Perl module.
|
|
66
|
+
|
|
67
|
+
## Warranty
|
|
68
|
+
|
|
69
|
+
This package is provided "as is" and without any express or
|
|
70
|
+
implied warranties, including, without limitation, the implied
|
|
71
|
+
warranties of merchantability and fitness for a particular purpose.
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
Apache-2.0
|
|
76
|
+
|
|
77
|
+
## Copyright
|
|
78
|
+
|
|
79
|
+
(C) 2006-2020, Daniel J. Berger
|
|
80
|
+
All Rights Reserved
|
|
81
|
+
|
|
82
|
+
## Author
|
|
83
|
+
|
|
84
|
+
Daniel J. Berger
|
data/Rakefile
CHANGED
|
@@ -1,29 +1,26 @@
|
|
|
1
|
-
require 'rake'
|
|
2
|
-
require 'rake/clean'
|
|
3
|
-
require '
|
|
4
|
-
|
|
5
|
-
CLEAN.include('**/*.gem', '**/*.rbc')
|
|
6
|
-
|
|
7
|
-
namespace :gem do
|
|
8
|
-
desc 'Build the attempt gem'
|
|
9
|
-
task :create => [:clean] do
|
|
10
|
-
require 'rubygems/package'
|
|
11
|
-
spec = eval(IO.read('attempt.gemspec'))
|
|
12
|
-
spec.signing_key = File.join(Dir.home, '.ssh', 'gem-private_key.pem')
|
|
13
|
-
Gem::Package.build(spec
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
desc "Install the attempt gem"
|
|
17
|
-
task :install => [:create] do
|
|
18
|
-
file = Dir["*.gem"].first
|
|
19
|
-
sh "gem install -l #{file}"
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
task :default => :test
|
|
1
|
+
require 'rake'
|
|
2
|
+
require 'rake/clean'
|
|
3
|
+
require 'rspec/core/rake_task'
|
|
4
|
+
|
|
5
|
+
CLEAN.include('**/*.gem', '**/*.rbc', '**/*.lock')
|
|
6
|
+
|
|
7
|
+
namespace :gem do
|
|
8
|
+
desc 'Build the attempt gem'
|
|
9
|
+
task :create => [:clean] do
|
|
10
|
+
require 'rubygems/package'
|
|
11
|
+
spec = eval(IO.read('attempt.gemspec'))
|
|
12
|
+
spec.signing_key = File.join(Dir.home, '.ssh', 'gem-private_key.pem')
|
|
13
|
+
Gem::Package.build(spec)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
desc "Install the attempt gem"
|
|
17
|
+
task :install => [:create] do
|
|
18
|
+
file = Dir["*.gem"].first
|
|
19
|
+
sh "gem install -l #{file}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
desc "Run the test suite"
|
|
24
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
25
|
+
|
|
26
|
+
task :default => :spec
|
data/attempt.gemspec
CHANGED
|
@@ -2,18 +2,16 @@ require 'rubygems'
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |spec|
|
|
4
4
|
spec.name = 'attempt'
|
|
5
|
-
spec.version = '0.
|
|
5
|
+
spec.version = '0.6.1'
|
|
6
6
|
spec.author = 'Daniel J. Berger'
|
|
7
|
-
spec.license = '
|
|
7
|
+
spec.license = 'Apache-2.0'
|
|
8
8
|
spec.email = 'djberg96@gmail.com'
|
|
9
9
|
spec.homepage = 'https://github.com/djberg96/attempt'
|
|
10
10
|
spec.summary = 'A thin wrapper for begin + rescue + sleep + retry'
|
|
11
|
-
spec.test_file = '
|
|
11
|
+
spec.test_file = 'spec/attempt_spec.rb'
|
|
12
12
|
spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
|
|
13
13
|
spec.cert_chain = Dir['certs/*']
|
|
14
14
|
|
|
15
|
-
spec.extra_rdoc_files = ['README','CHANGES','MANIFEST']
|
|
16
|
-
|
|
17
15
|
spec.metadata = {
|
|
18
16
|
'changelog_uri' => 'https://github.com/djberg96/attempt/blob/master/CHANGES',
|
|
19
17
|
'source_code_uri' => 'https://github.com/djberg96/attempt/blob/master/lib/attempt.rb',
|
|
@@ -21,13 +19,14 @@ Gem::Specification.new do |spec|
|
|
|
21
19
|
'wiki_uri' => 'https://github.com/djberg96/attempt/wiki'
|
|
22
20
|
}
|
|
23
21
|
|
|
24
|
-
spec.add_dependency('structured_warnings', '~> 0.
|
|
25
|
-
spec.
|
|
22
|
+
spec.add_dependency('structured_warnings', '~> 0.4.0')
|
|
23
|
+
spec.add_dependency('safe_timeout', '~> 0.0.5')
|
|
24
|
+
spec.add_dependency('rspec', '~> 3.9')
|
|
26
25
|
|
|
27
26
|
spec.description = <<-EOF
|
|
28
27
|
The attempt library provides a thin wrapper for the typical
|
|
29
28
|
begin/rescue/sleep/retry dance. Use this in order to robustly
|
|
30
|
-
handle blocks of code that could briefly flake out, such as
|
|
29
|
+
handle blocks of code that could briefly flake out, such as an http
|
|
31
30
|
or database connection, where it's often better to try again after
|
|
32
31
|
a brief period rather than fail immediately.
|
|
33
32
|
EOF
|
data/certs/djberg96_pub.pem
CHANGED
|
@@ -1,21 +1,26 @@
|
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
|
2
|
-
|
|
2
|
+
MIIEcDCCAtigAwIBAgIBATANBgkqhkiG9w0BAQsFADA/MREwDwYDVQQDDAhkamJl
|
|
3
3
|
cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
|
|
4
|
-
|
|
4
|
+
MB4XDTE4MDMxODE1MjIwN1oXDTI4MDMxNTE1MjIwN1owPzERMA8GA1UEAwwIZGpi
|
|
5
5
|
ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
6
|
+
bTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALgfaroVM6CI06cxr0/h
|
|
7
|
+
A+j+pc8fgpRgBVmHFaFunq28GPC3IvW7Nvc3Y8SnAW7pP1EQIbhlwRIaQzJ93/yj
|
|
8
|
+
u95KpkP7tA9erypnV7dpzBkzNlX14ACaFD/6pHoXoe2ltBxk3CCyyzx70mTqJpph
|
|
9
|
+
75IB03ni9a8yqn8pmse+s83bFJOAqddSj009sGPcQO+QOWiNxqYv1n5EHcvj2ebO
|
|
10
|
+
6hN7YTmhx7aSia4qL/quc4DlIaGMWoAhvML7u1fmo53CYxkKskfN8MOecq2vfEmL
|
|
11
|
+
iLu+SsVVEAufMDDFMXMJlvDsviolUSGMSNRTujkyCcJoXKYYxZSNtIiyd9etI0X3
|
|
12
|
+
ctu0uhrFyrMZXCedutvXNjUolD5r9KGBFSWH1R9u2I3n3SAyFF2yzv/7idQHLJJq
|
|
13
|
+
74BMnx0FIq6fCpu5slAipvxZ3ZkZpEXZFr3cIBtO1gFvQWW7E/Y3ijliWJS1GQFq
|
|
14
|
+
058qERadHGu1yu1dojmFRo6W2KZvY9al2yIlbkpDrD5MYQIDAQABo3cwdTAJBgNV
|
|
15
|
+
HRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUFZsMapgzJimzsbaBG2Tm8j5e
|
|
16
|
+
AzgwHQYDVR0RBBYwFIESZGpiZXJnOTZAZ21haWwuY29tMB0GA1UdEgQWMBSBEmRq
|
|
17
|
+
YmVyZzk2QGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAYEAW2tnYixXQtKxgGXq
|
|
18
|
+
/3iSWG2bLwvxS4go3srO+aRXZHrFUMlJ5W0mCxl03aazxxKTsVVpZD8QZxvK91OQ
|
|
19
|
+
h9zr9JBYqCLcCVbr8SkmYCi/laxIZxsNE5YI8cC8vvlLI7AMgSfPSnn/Epq1GjGY
|
|
20
|
+
6L1iRcEDtanGCIvjqlCXO9+BmsnCfEVehqZkQHeYczA03tpOWb6pon2wzvMKSsKH
|
|
21
|
+
ks0ApVdstSLz1kzzAqem/uHdG9FyXdbTAwH1G4ZPv69sQAFAOCgAqYmdnzedsQtE
|
|
22
|
+
1LQfaQrx0twO+CZJPcRLEESjq8ScQxWRRkfuh2VeR7cEU7L7KqT10mtUwrvw7APf
|
|
23
|
+
DYoeCY9KyjIBjQXfbj2ke5u1hZj94Fsq9FfbEQg8ygCgwThnmkTrrKEiMSs3alYR
|
|
24
|
+
ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
|
|
25
|
+
WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
|
|
21
26
|
-----END CERTIFICATE-----
|
data/lib/attempt.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'safe_timeout'
|
|
2
2
|
require 'structured_warnings'
|
|
3
3
|
|
|
4
4
|
# The Attempt class encapsulates methods related to multiple attempts at
|
|
@@ -6,7 +6,7 @@ require 'structured_warnings'
|
|
|
6
6
|
class Attempt
|
|
7
7
|
|
|
8
8
|
# The version of the attempt library.
|
|
9
|
-
VERSION = '0.
|
|
9
|
+
VERSION = '0.6.1'.freeze
|
|
10
10
|
|
|
11
11
|
# Warning raised if an attempt fails before the maximum number of tries
|
|
12
12
|
# has been reached.
|
|
@@ -38,21 +38,34 @@ class Attempt
|
|
|
38
38
|
attr_accessor :level
|
|
39
39
|
|
|
40
40
|
# :call-seq:
|
|
41
|
-
# Attempt.new
|
|
41
|
+
# Attempt.new(**kwargs)
|
|
42
42
|
#
|
|
43
|
-
# Creates and returns a new +Attempt+ object.
|
|
44
|
-
#
|
|
43
|
+
# Creates and returns a new +Attempt+ object. The supported keyword options
|
|
44
|
+
# are as follows:
|
|
45
45
|
#
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
46
|
+
# * tries - The number of attempts to make before giving up. The default is 3.
|
|
47
|
+
# * interval - The delay in seconds between each attempt. The default is 60.
|
|
48
|
+
# * log - An IO handle or Logger instance where warnings/errors are logged to. The default is nil.
|
|
49
|
+
# * increment - The amount to increment the interval between tries. The default is 0.
|
|
50
|
+
# * level - The level of exception to be caught. The default is everything, i.e. Exception.
|
|
51
|
+
# * warnings - Boolean value that indicates whether or not errors are treated as warnings
|
|
52
|
+
# until the maximum number of attempts has been made. The default is true.
|
|
53
|
+
# * timeout - Boolean value to indicate whether or not to automatically wrap your
|
|
54
|
+
# proc in a SafeTimeout block. The default is false.
|
|
55
|
+
#
|
|
56
|
+
# Example:
|
|
57
|
+
#
|
|
58
|
+
# a = Attempt.new(tries: 5, increment: 10, timeout: true)
|
|
59
|
+
# a.attempt{ http.get("http://something.foo.com") }
|
|
60
|
+
#
|
|
61
|
+
def initialize(**options)
|
|
62
|
+
@tries = options[:tries] || 3 # Reasonable default
|
|
63
|
+
@interval = options[:interval] || 60 # Reasonable default
|
|
64
|
+
@log = options[:log] # Should be an IO handle, if provided
|
|
65
|
+
@increment = options[:increment] || 0 # Should be an integer, if provided
|
|
66
|
+
@timeout = options[:timeout] || false # Wrap the code in a timeout block if provided
|
|
67
|
+
@level = options[:level] || Exception # Level of exception to be caught
|
|
68
|
+
@warnings = options[:warnings] || true # Errors are sent to STDERR as warnings if true
|
|
56
69
|
end
|
|
57
70
|
|
|
58
71
|
# Attempt to perform the operation in the provided block up to +tries+
|
|
@@ -65,7 +78,7 @@ class Attempt
|
|
|
65
78
|
count = 1
|
|
66
79
|
begin
|
|
67
80
|
if @timeout
|
|
68
|
-
|
|
81
|
+
SafeTimeout.timeout(@timeout){ yield }
|
|
69
82
|
else
|
|
70
83
|
yield
|
|
71
84
|
end
|
|
@@ -75,7 +88,11 @@ class Attempt
|
|
|
75
88
|
msg = "Error on attempt # #{count}: #{error}; retrying"
|
|
76
89
|
count += 1
|
|
77
90
|
warn Warning, msg if @warnings
|
|
78
|
-
|
|
91
|
+
|
|
92
|
+
if @log # Accept an IO or Logger object
|
|
93
|
+
@log.respond_to?(:puts) ? @log.puts(msg) : @log.warn(msg)
|
|
94
|
+
end
|
|
95
|
+
|
|
79
96
|
@interval += @increment if @increment
|
|
80
97
|
sleep @interval
|
|
81
98
|
retry
|
|
@@ -87,34 +104,28 @@ end
|
|
|
87
104
|
|
|
88
105
|
module Kernel
|
|
89
106
|
# :call-seq:
|
|
90
|
-
# attempt(tries
|
|
107
|
+
# attempt(tries: 3, interval: 60, timeout: 10){ # some op }
|
|
91
108
|
#
|
|
92
109
|
# Attempt to perform the operation in the provided block up to +tries+
|
|
93
|
-
# times, sleeping +interval+ between each try.
|
|
110
|
+
# times, sleeping +interval+ between each try. By default the number
|
|
94
111
|
# of tries defaults to 3, the interval defaults to 60 seconds, and there
|
|
95
112
|
# is no timeout specified.
|
|
96
113
|
#
|
|
97
114
|
# If +timeout+ is provided then the operation is wrapped in a Timeout
|
|
98
|
-
# block as well.
|
|
115
|
+
# block as well. This is handy for those rare occasions when an IO
|
|
99
116
|
# connection could hang indefinitely, for example.
|
|
100
117
|
#
|
|
101
118
|
# If the operation still fails the (last) error is then re-raised.
|
|
102
119
|
#
|
|
103
|
-
# This is really just a wrapper for Attempt.new
|
|
104
|
-
# good enough i.e. you don't care about warnings, increments or logging,
|
|
105
|
-
# and you want a little added convenience.
|
|
120
|
+
# This is really just a convenient wrapper for Attempt.new + Attempt#attempt.
|
|
106
121
|
#
|
|
107
122
|
# Example:
|
|
108
123
|
#
|
|
109
124
|
# # Make 3 attempts to connect to the database, 60 seconds apart.
|
|
110
125
|
# attempt{ DBI.connect(dsn, user, passwd) }
|
|
111
126
|
#
|
|
112
|
-
def attempt(
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
a.tries = tries
|
|
116
|
-
a.interval = interval
|
|
117
|
-
a.timeout = timeout if timeout
|
|
118
|
-
}.attempt(&block)
|
|
127
|
+
def attempt(**kwargs, &block)
|
|
128
|
+
object = Attempt.new(kwargs)
|
|
129
|
+
object.attempt(&block)
|
|
119
130
|
end
|
|
120
131
|
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#####################################################################
|
|
2
|
+
# attempt_spec.rb
|
|
3
|
+
#
|
|
4
|
+
# Tests for the attempt library. You should run this test case via
|
|
5
|
+
# the 'rake test' Rakefile task (or just 'rake').
|
|
6
|
+
#
|
|
7
|
+
# TODO: Test that an Attempt::Warning is raised.
|
|
8
|
+
#####################################################################
|
|
9
|
+
require 'rspec'
|
|
10
|
+
require 'attempt'
|
|
11
|
+
require 'stringio'
|
|
12
|
+
|
|
13
|
+
RSpec.describe Attempt do
|
|
14
|
+
before(:all) do
|
|
15
|
+
$stderr = StringIO.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
before do
|
|
19
|
+
@tries = 2
|
|
20
|
+
@interval = 0.1
|
|
21
|
+
@timeout = 0.1
|
|
22
|
+
$value = 0
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
example "version constant is set to expected value" do
|
|
26
|
+
expect(Attempt::VERSION).to eq('0.6.1')
|
|
27
|
+
expect(Attempt::VERSION).to be_frozen
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
example "attempt works as expected without arguments" do
|
|
31
|
+
expect{ attempt{ 2 + 2 } }.not_to raise_error
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
example "attempt retries the number of times specified" do
|
|
35
|
+
expect{ attempt(tries: @tries){ $value += 1; raise if $value < 2 } }.not_to raise_error
|
|
36
|
+
expect($value).to eq(2)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
example "attempt retries the number of times specified with interval" do
|
|
40
|
+
expect{
|
|
41
|
+
attempt(tries: @tries, interval: @interval){ $value += 1; raise if $value < 2 }
|
|
42
|
+
}.not_to raise_error
|
|
43
|
+
expect($value).to eq(2)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
example "attempt retries the number of times specified with interval and timeout" do
|
|
47
|
+
expect{
|
|
48
|
+
attempt(tries: @tries, interval: @interval, timeout: @timeout){ $value += 1; raise if $value < 2 }
|
|
49
|
+
}.not_to raise_error
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
example "attempt raises a timeout error if timeout value is exceeded" do
|
|
53
|
+
expect{ attempt(tries: 1, interval: 1, timeout: @timeout){ sleep 5 } }.to raise_error(Timeout::Error)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
example "attempt raises exception as expected" do
|
|
57
|
+
expect{ attempt(tries: 2, interval: 2){ raise } }.to raise_error(RuntimeError)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
after do
|
|
61
|
+
$after = 0
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
after(:all) do
|
|
65
|
+
$stderr = STDERR
|
|
66
|
+
end
|
|
67
|
+
end
|
metadata
CHANGED
|
@@ -1,36 +1,41 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: attempt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel J. Berger
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain:
|
|
11
11
|
- |
|
|
12
12
|
-----BEGIN CERTIFICATE-----
|
|
13
|
-
|
|
13
|
+
MIIEcDCCAtigAwIBAgIBATANBgkqhkiG9w0BAQsFADA/MREwDwYDVQQDDAhkamJl
|
|
14
14
|
cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
|
|
15
|
-
|
|
15
|
+
MB4XDTE4MDMxODE1MjIwN1oXDTI4MDMxNTE1MjIwN1owPzERMA8GA1UEAwwIZGpi
|
|
16
16
|
ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
bTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALgfaroVM6CI06cxr0/h
|
|
18
|
+
A+j+pc8fgpRgBVmHFaFunq28GPC3IvW7Nvc3Y8SnAW7pP1EQIbhlwRIaQzJ93/yj
|
|
19
|
+
u95KpkP7tA9erypnV7dpzBkzNlX14ACaFD/6pHoXoe2ltBxk3CCyyzx70mTqJpph
|
|
20
|
+
75IB03ni9a8yqn8pmse+s83bFJOAqddSj009sGPcQO+QOWiNxqYv1n5EHcvj2ebO
|
|
21
|
+
6hN7YTmhx7aSia4qL/quc4DlIaGMWoAhvML7u1fmo53CYxkKskfN8MOecq2vfEmL
|
|
22
|
+
iLu+SsVVEAufMDDFMXMJlvDsviolUSGMSNRTujkyCcJoXKYYxZSNtIiyd9etI0X3
|
|
23
|
+
ctu0uhrFyrMZXCedutvXNjUolD5r9KGBFSWH1R9u2I3n3SAyFF2yzv/7idQHLJJq
|
|
24
|
+
74BMnx0FIq6fCpu5slAipvxZ3ZkZpEXZFr3cIBtO1gFvQWW7E/Y3ijliWJS1GQFq
|
|
25
|
+
058qERadHGu1yu1dojmFRo6W2KZvY9al2yIlbkpDrD5MYQIDAQABo3cwdTAJBgNV
|
|
26
|
+
HRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUFZsMapgzJimzsbaBG2Tm8j5e
|
|
27
|
+
AzgwHQYDVR0RBBYwFIESZGpiZXJnOTZAZ21haWwuY29tMB0GA1UdEgQWMBSBEmRq
|
|
28
|
+
YmVyZzk2QGdtYWlsLmNvbTANBgkqhkiG9w0BAQsFAAOCAYEAW2tnYixXQtKxgGXq
|
|
29
|
+
/3iSWG2bLwvxS4go3srO+aRXZHrFUMlJ5W0mCxl03aazxxKTsVVpZD8QZxvK91OQ
|
|
30
|
+
h9zr9JBYqCLcCVbr8SkmYCi/laxIZxsNE5YI8cC8vvlLI7AMgSfPSnn/Epq1GjGY
|
|
31
|
+
6L1iRcEDtanGCIvjqlCXO9+BmsnCfEVehqZkQHeYczA03tpOWb6pon2wzvMKSsKH
|
|
32
|
+
ks0ApVdstSLz1kzzAqem/uHdG9FyXdbTAwH1G4ZPv69sQAFAOCgAqYmdnzedsQtE
|
|
33
|
+
1LQfaQrx0twO+CZJPcRLEESjq8ScQxWRRkfuh2VeR7cEU7L7KqT10mtUwrvw7APf
|
|
34
|
+
DYoeCY9KyjIBjQXfbj2ke5u1hZj94Fsq9FfbEQg8ygCgwThnmkTrrKEiMSs3alYR
|
|
35
|
+
ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
|
|
36
|
+
WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
|
|
32
37
|
-----END CERTIFICATE-----
|
|
33
|
-
date:
|
|
38
|
+
date: 2020-10-20 00:00:00.000000000 Z
|
|
34
39
|
dependencies:
|
|
35
40
|
- !ruby/object:Gem::Dependency
|
|
36
41
|
name: structured_warnings
|
|
@@ -38,62 +43,72 @@ dependencies:
|
|
|
38
43
|
requirements:
|
|
39
44
|
- - "~>"
|
|
40
45
|
- !ruby/object:Gem::Version
|
|
41
|
-
version: 0.
|
|
46
|
+
version: 0.4.0
|
|
42
47
|
type: :runtime
|
|
43
48
|
prerelease: false
|
|
44
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
45
50
|
requirements:
|
|
46
51
|
- - "~>"
|
|
47
52
|
- !ruby/object:Gem::Version
|
|
48
|
-
version: 0.
|
|
53
|
+
version: 0.4.0
|
|
49
54
|
- !ruby/object:Gem::Dependency
|
|
50
|
-
name:
|
|
55
|
+
name: safe_timeout
|
|
51
56
|
requirement: !ruby/object:Gem::Requirement
|
|
52
57
|
requirements:
|
|
53
|
-
- - "
|
|
58
|
+
- - "~>"
|
|
54
59
|
- !ruby/object:Gem::Version
|
|
55
|
-
version:
|
|
56
|
-
type: :
|
|
60
|
+
version: 0.0.5
|
|
61
|
+
type: :runtime
|
|
57
62
|
prerelease: false
|
|
58
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
59
64
|
requirements:
|
|
60
|
-
- - "
|
|
65
|
+
- - "~>"
|
|
61
66
|
- !ruby/object:Gem::Version
|
|
62
|
-
version:
|
|
67
|
+
version: 0.0.5
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: rspec
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '3.9'
|
|
75
|
+
type: :runtime
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '3.9'
|
|
63
82
|
description: |2
|
|
64
83
|
The attempt library provides a thin wrapper for the typical
|
|
65
84
|
begin/rescue/sleep/retry dance. Use this in order to robustly
|
|
66
|
-
handle blocks of code that could briefly flake out, such as
|
|
85
|
+
handle blocks of code that could briefly flake out, such as an http
|
|
67
86
|
or database connection, where it's often better to try again after
|
|
68
87
|
a brief period rather than fail immediately.
|
|
69
88
|
email: djberg96@gmail.com
|
|
70
89
|
executables: []
|
|
71
90
|
extensions: []
|
|
72
|
-
extra_rdoc_files:
|
|
73
|
-
- README
|
|
74
|
-
- CHANGES
|
|
75
|
-
- MANIFEST
|
|
91
|
+
extra_rdoc_files: []
|
|
76
92
|
files:
|
|
93
|
+
- CHANGES.md
|
|
94
|
+
- Gemfile
|
|
95
|
+
- LICENSE
|
|
96
|
+
- MANIFEST.md
|
|
97
|
+
- README.md
|
|
98
|
+
- Rakefile
|
|
77
99
|
- attempt.gemspec
|
|
78
|
-
- certs
|
|
79
100
|
- certs/djberg96_pub.pem
|
|
80
|
-
- CHANGES
|
|
81
|
-
- lib
|
|
82
101
|
- lib/attempt.rb
|
|
83
|
-
-
|
|
84
|
-
- Rakefile
|
|
85
|
-
- README
|
|
86
|
-
- test
|
|
87
|
-
- test/test_attempt.rb
|
|
102
|
+
- spec/attempt_spec.rb
|
|
88
103
|
homepage: https://github.com/djberg96/attempt
|
|
89
104
|
licenses:
|
|
90
|
-
-
|
|
105
|
+
- Apache-2.0
|
|
91
106
|
metadata:
|
|
92
107
|
changelog_uri: https://github.com/djberg96/attempt/blob/master/CHANGES
|
|
93
108
|
source_code_uri: https://github.com/djberg96/attempt/blob/master/lib/attempt.rb
|
|
94
109
|
bug_tracker_uri: https://github.com/djberg96/attempt/issues
|
|
95
110
|
wiki_uri: https://github.com/djberg96/attempt/wiki
|
|
96
|
-
post_install_message:
|
|
111
|
+
post_install_message:
|
|
97
112
|
rdoc_options: []
|
|
98
113
|
require_paths:
|
|
99
114
|
- lib
|
|
@@ -108,10 +123,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
108
123
|
- !ruby/object:Gem::Version
|
|
109
124
|
version: '0'
|
|
110
125
|
requirements: []
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
signing_key:
|
|
126
|
+
rubygems_version: 3.1.4
|
|
127
|
+
signing_key:
|
|
114
128
|
specification_version: 4
|
|
115
129
|
summary: A thin wrapper for begin + rescue + sleep + retry
|
|
116
130
|
test_files:
|
|
117
|
-
-
|
|
131
|
+
- spec/attempt_spec.rb
|
metadata.gz.sig
CHANGED
|
Binary file
|
data/MANIFEST
DELETED
data/README
DELETED
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
== Description
|
|
2
|
-
A thin wrapper for begin + rescue + sleep + retry.
|
|
3
|
-
|
|
4
|
-
== Installation
|
|
5
|
-
gem install attempt
|
|
6
|
-
|
|
7
|
-
== Synopsis
|
|
8
|
-
require 'attempt'
|
|
9
|
-
|
|
10
|
-
# Attempt to ftp to some host, trying 3 times with 30 seconds between
|
|
11
|
-
# attempts before finally raising an error.
|
|
12
|
-
#
|
|
13
|
-
attempt(3, 30){
|
|
14
|
-
Net::FTP.open(host, user, passwd){ ... }
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
# Or, do things the long way...
|
|
18
|
-
code = Attempt.new{ |a|
|
|
19
|
-
a.tries = 3
|
|
20
|
-
a.interval = 30
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
code.attempt{
|
|
24
|
-
Net::FTP.open(host, user, passwd){ ... }
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
== Known Bugs
|
|
28
|
-
None that I'm aware of. If you find any bugs, please log them on the
|
|
29
|
-
project page at:
|
|
30
|
-
|
|
31
|
-
https://github.com/djberg96/attempt
|
|
32
|
-
|
|
33
|
-
== Caveats
|
|
34
|
-
Use with caution. Specifically, make sure you aren't inadvertantly
|
|
35
|
-
wrapping code that already performs sleep + retry. Otherwise, you'll
|
|
36
|
-
end up with a series of nested retry's that could take much longer to
|
|
37
|
-
work than you expect.
|
|
38
|
-
|
|
39
|
-
Also, this library uses the timeout library internally, which has some
|
|
40
|
-
known issues. See Future Plans, below.
|
|
41
|
-
|
|
42
|
-
As of version 0.3.0, this library requires structured_warnings 0.3.0 or
|
|
43
|
-
later. This is necessary because of changes in Ruby 2.4.
|
|
44
|
-
|
|
45
|
-
== Future Plans
|
|
46
|
-
Add the ability to set an absolute maximum number of seconds to prevent
|
|
47
|
-
nested sleep/retry from delaying attempts longer than expected.
|
|
48
|
-
|
|
49
|
-
Replace the timeout library with a self selecting pipe if possible.
|
|
50
|
-
|
|
51
|
-
== Acknowledgements
|
|
52
|
-
This library is partially based on Mark Fowler's 'Attempt' Perl module.
|
|
53
|
-
|
|
54
|
-
== Warranty
|
|
55
|
-
This package is provided "as is" and without any express or
|
|
56
|
-
implied warranties, including, without limitation, the implied
|
|
57
|
-
warranties of merchantability and fitness for a particular purpose.
|
|
58
|
-
|
|
59
|
-
== License
|
|
60
|
-
Artistic 2.0
|
|
61
|
-
|
|
62
|
-
== Copyright
|
|
63
|
-
(C) 2006-2017, Daniel J. Berger
|
|
64
|
-
All Rights Reserved
|
|
65
|
-
|
|
66
|
-
== Author
|
|
67
|
-
Daniel J. Berger
|
data/test/test_attempt.rb
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#####################################################################
|
|
2
|
-
# test_attempt.rb
|
|
3
|
-
#
|
|
4
|
-
# Test case for the attempt library. You should run this test case
|
|
5
|
-
# via the 'rake test' Rakefile task.
|
|
6
|
-
#
|
|
7
|
-
# TODO: Test that an Attempt::Warning is raised.
|
|
8
|
-
#####################################################################
|
|
9
|
-
require 'test-unit'
|
|
10
|
-
require 'attempt'
|
|
11
|
-
require 'stringio'
|
|
12
|
-
|
|
13
|
-
class TC_Attempt < Test::Unit::TestCase
|
|
14
|
-
def self.startup
|
|
15
|
-
$stderr = StringIO.new
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def setup
|
|
19
|
-
@tries = 2
|
|
20
|
-
@interval = 0.1
|
|
21
|
-
@timeout = 0.1
|
|
22
|
-
$value = 0
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
test "version constant is set to expected value" do
|
|
26
|
-
assert_equal('0.3.2', Attempt::VERSION)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
test "attempt works as expected without arguments" do
|
|
30
|
-
assert_nothing_raised{ attempt{ 2 + 2 } }
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
test "attempt retries the number of times specified" do
|
|
34
|
-
assert_nothing_raised{ attempt(@tries){ $value += 1; raise if $value < 2 } }
|
|
35
|
-
assert_equal(2, $value)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
test "attempt retries the number of times specified with interval" do
|
|
39
|
-
assert_nothing_raised{ attempt(@tries, @interval){ $value += 1; raise if $value < 2 } }
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
test "attempt retries the number of times specified with interval and timeout" do
|
|
43
|
-
assert_nothing_raised{ attempt(@tries, @interval, @timeout){ $value += 1; raise if $value < 2 } }
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
test "attempt raises a timeout error if timeout value is exceeded" do
|
|
47
|
-
assert_raises(Timeout::Error){ attempt(1, 1, @timeout){ sleep 5 } }
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
test "attempt raises exception as expected" do
|
|
51
|
-
assert_raises(RuntimeError){ attempt(2, 2){ raise } }
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def teardown
|
|
55
|
-
@tries = nil
|
|
56
|
-
@interval = nil
|
|
57
|
-
@timeout = nil
|
|
58
|
-
$value = 0
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def self.shutdown
|
|
62
|
-
$stderr = STDERR
|
|
63
|
-
end
|
|
64
|
-
end
|