exceptional_synchrony 1.0.1 → 1.1.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
- data/.dependabot/config.yml +10 -0
- data/.gitignore +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +10 -1
- data/Gemfile.lock +104 -101
- data/Rakefile +10 -0
- data/exceptional_synchrony.gemspec +20 -22
- data/lib/exceptional_synchrony/callback_exceptions.rb +36 -4
- data/lib/exceptional_synchrony/event_machine_proxy.rb +18 -0
- data/lib/exceptional_synchrony/limited_work_queue.rb +29 -5
- data/lib/exceptional_synchrony/parallel_sync.rb +1 -0
- data/lib/exceptional_synchrony/version.rb +1 -1
- data/lib/exceptional_synchrony.rb +0 -1
- data/semaphore_ci/setup.sh +3 -0
- data/test/test_helper.rb +7 -0
- data/test/unit/callback_exceptions_test.rb +67 -15
- data/test/unit/event_machine_proxy_test.rb +43 -5
- data/test/unit/limited_work_queue_test.rb +221 -23
- data/test/unit/parallel_sync_test.rb +6 -6
- metadata +35 -87
- data/Thorfile +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 883532dc8502a497eabb0785806a621f034463c021e676526ff70a5c4119d5c1
|
4
|
+
data.tar.gz: 927c40e91113f1c0fb6828f400253c18fa6abcb1fec772327913a966a21fdc9c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb19bc5fbcdd191ef8ea84acb72fae37c8b32a042fccfa15de3e6b0b41d9f6fc5a7d3a4aa488da6d337e60bf6f1ca93b9e1ff948c3ed2e4f948b92b576fc1a76
|
7
|
+
data.tar.gz: 9ea68a7d671a07e59a09b4cf56c99562db38b83decd54b7399e45a54e8f7ac7fedca70c5e20ab319b90a054dda758eed701497683b9b5f39f0fd52ee79c3b590
|
data/.gitignore
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.6.5
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# CHANGELOG for `exceptional_synchrony`
|
2
|
+
|
3
|
+
Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
4
|
+
|
5
|
+
Note: This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
All notable changes to this project will be documented in this file.
|
8
|
+
## [1.1.1] - 2020-05-03
|
9
|
+
- Replace hobo_support with invoca_utils
|
10
|
+
|
11
|
+
[1.1.1]: https://github.com/Invoca/exceptional_synchrony/compare/v1.1.0...v1.1.1
|
data/Gemfile
CHANGED
@@ -1,6 +1,15 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
5
|
# Specify your gem's dependencies in attr_default.gemspec
|
6
6
|
gemspec
|
7
|
+
|
8
|
+
group :development do
|
9
|
+
gem 'minitest'
|
10
|
+
gem 'pry'
|
11
|
+
gem 'rake'
|
12
|
+
gem 'rr', '~> 1.2'
|
13
|
+
gem 'thor'
|
14
|
+
gem 'webmock', '~> 1.24'
|
15
|
+
end
|
data/Gemfile.lock
CHANGED
@@ -1,121 +1,119 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
exceptional_synchrony (1.
|
4
|
+
exceptional_synchrony (1.1.1)
|
5
5
|
em-http-request
|
6
|
-
em-synchrony
|
7
|
-
eventmachine
|
8
|
-
exception_handling
|
9
|
-
|
6
|
+
em-synchrony
|
7
|
+
eventmachine
|
8
|
+
exception_handling (~> 2.2)
|
9
|
+
invoca-utils (~> 0.3)
|
10
10
|
|
11
11
|
GEM
|
12
12
|
remote: https://rubygems.org/
|
13
13
|
specs:
|
14
|
-
actionmailer (
|
15
|
-
actionpack (=
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
14
|
+
actionmailer (4.2.11.1)
|
15
|
+
actionpack (= 4.2.11.1)
|
16
|
+
actionview (= 4.2.11.1)
|
17
|
+
activejob (= 4.2.11.1)
|
18
|
+
mail (~> 2.5, >= 2.5.4)
|
19
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
20
|
+
actionpack (4.2.11.1)
|
21
|
+
actionview (= 4.2.11.1)
|
22
|
+
activesupport (= 4.2.11.1)
|
23
|
+
rack (~> 1.6)
|
24
|
+
rack-test (~> 0.6.2)
|
25
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
26
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
27
|
+
actionview (4.2.11.1)
|
28
|
+
activesupport (= 4.2.11.1)
|
29
|
+
builder (~> 3.1)
|
21
30
|
erubis (~> 2.7.0)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
crack (0.4.1)
|
46
|
-
safe_yaml (~> 0.9.0)
|
47
|
-
em-http-request (1.1.2)
|
31
|
+
rails-dom-testing (~> 1.0, >= 1.0.5)
|
32
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
33
|
+
activejob (4.2.11.1)
|
34
|
+
activesupport (= 4.2.11.1)
|
35
|
+
globalid (>= 0.3.0)
|
36
|
+
activesupport (4.2.11.1)
|
37
|
+
i18n (~> 0.7)
|
38
|
+
minitest (~> 5.1)
|
39
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
40
|
+
tzinfo (~> 1.1)
|
41
|
+
addressable (2.7.0)
|
42
|
+
public_suffix (>= 2.0.2, < 5.0)
|
43
|
+
builder (3.2.4)
|
44
|
+
coderay (1.1.2)
|
45
|
+
concurrent-ruby (1.1.6)
|
46
|
+
contextual_logger (0.6.1)
|
47
|
+
activesupport
|
48
|
+
json
|
49
|
+
cookiejar (0.3.3)
|
50
|
+
crack (0.4.3)
|
51
|
+
safe_yaml (~> 1.0.0)
|
52
|
+
crass (1.0.6)
|
53
|
+
em-http-request (1.1.5)
|
48
54
|
addressable (>= 2.3.4)
|
49
|
-
cookiejar
|
55
|
+
cookiejar (!= 0.3.1)
|
50
56
|
em-socksify (>= 0.3)
|
51
57
|
eventmachine (>= 1.0.3)
|
52
58
|
http_parser.rb (>= 0.6.0)
|
53
|
-
em-socksify (0.3.
|
59
|
+
em-socksify (0.3.2)
|
54
60
|
eventmachine (>= 1.0.0.beta.4)
|
55
|
-
em-synchrony (1.0.
|
61
|
+
em-synchrony (1.0.6)
|
56
62
|
eventmachine (>= 1.0.0.beta.1)
|
57
63
|
erubis (2.7.0)
|
58
|
-
eventmachine (1.
|
59
|
-
exception_handling (
|
60
|
-
actionmailer (
|
61
|
-
actionpack (
|
62
|
-
activesupport (
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
eventmachine (1.2.7)
|
65
|
+
exception_handling (2.4.1)
|
66
|
+
actionmailer (~> 4.2)
|
67
|
+
actionpack (~> 4.2)
|
68
|
+
activesupport (~> 4.2)
|
69
|
+
contextual_logger
|
70
|
+
eventmachine (~> 1.0)
|
71
|
+
invoca-utils (~> 0.3)
|
72
|
+
globalid (0.4.2)
|
73
|
+
activesupport (>= 4.2.0)
|
74
|
+
hashdiff (1.0.1)
|
67
75
|
http_parser.rb (0.6.0)
|
68
|
-
i18n (0.
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
76
|
+
i18n (0.9.5)
|
77
|
+
concurrent-ruby (~> 1.0)
|
78
|
+
invoca-utils (0.3.0)
|
79
|
+
json (2.3.0)
|
80
|
+
loofah (2.5.0)
|
81
|
+
crass (~> 1.0.2)
|
82
|
+
nokogiri (>= 1.5.9)
|
83
|
+
mail (2.7.1)
|
84
|
+
mini_mime (>= 0.1.1)
|
85
|
+
method_source (1.0.0)
|
86
|
+
mini_mime (1.0.2)
|
87
|
+
mini_portile2 (2.4.0)
|
88
|
+
minitest (5.14.0)
|
89
|
+
nokogiri (1.10.9)
|
90
|
+
mini_portile2 (~> 2.4.0)
|
91
|
+
pry (0.13.1)
|
92
|
+
coderay (~> 1.1)
|
93
|
+
method_source (~> 1.0)
|
94
|
+
public_suffix (4.0.4)
|
95
|
+
rack (1.6.13)
|
96
|
+
rack-test (0.6.3)
|
84
97
|
rack (>= 1.0)
|
85
|
-
rails (
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
json (~> 1.4)
|
103
|
-
rr (1.1.2)
|
104
|
-
safe_yaml (0.9.7)
|
105
|
-
sprockets (2.2.2)
|
106
|
-
hike (~> 1.2)
|
107
|
-
multi_json (~> 1.0)
|
108
|
-
rack (~> 1.0)
|
109
|
-
tilt (~> 1.1, != 1.3.0)
|
110
|
-
thor (0.18.1)
|
111
|
-
tilt (1.4.1)
|
112
|
-
treetop (1.4.15)
|
113
|
-
polyglot
|
114
|
-
polyglot (>= 0.3.1)
|
115
|
-
tzinfo (0.3.38)
|
116
|
-
webmock (1.17.1)
|
117
|
-
addressable (>= 2.2.7)
|
98
|
+
rails-deprecated_sanitizer (1.0.3)
|
99
|
+
activesupport (>= 4.2.0.alpha)
|
100
|
+
rails-dom-testing (1.0.9)
|
101
|
+
activesupport (>= 4.2.0, < 5.0)
|
102
|
+
nokogiri (~> 1.6)
|
103
|
+
rails-deprecated_sanitizer (>= 1.0.1)
|
104
|
+
rails-html-sanitizer (1.3.0)
|
105
|
+
loofah (~> 2.3)
|
106
|
+
rake (13.0.1)
|
107
|
+
rr (1.2.1)
|
108
|
+
safe_yaml (1.0.5)
|
109
|
+
thor (1.0.1)
|
110
|
+
thread_safe (0.3.6)
|
111
|
+
tzinfo (1.2.7)
|
112
|
+
thread_safe (~> 0.1)
|
113
|
+
webmock (1.24.6)
|
114
|
+
addressable (>= 2.3.6)
|
118
115
|
crack (>= 0.3.2)
|
116
|
+
hashdiff
|
119
117
|
|
120
118
|
PLATFORMS
|
121
119
|
ruby
|
@@ -123,6 +121,11 @@ PLATFORMS
|
|
123
121
|
DEPENDENCIES
|
124
122
|
exceptional_synchrony!
|
125
123
|
minitest
|
126
|
-
|
124
|
+
pry
|
125
|
+
rake
|
126
|
+
rr (~> 1.2)
|
127
127
|
thor
|
128
|
-
webmock (~> 1.
|
128
|
+
webmock (~> 1.24)
|
129
|
+
|
130
|
+
BUNDLED WITH
|
131
|
+
1.17.3
|
data/Rakefile
CHANGED
@@ -1,26 +1,24 @@
|
|
1
1
|
require File.expand_path('../lib/exceptional_synchrony/version', __FILE__)
|
2
2
|
|
3
|
-
Gem::Specification.new do |
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'exceptional_synchrony'
|
5
|
+
spec.date = '2014-01-16'
|
6
|
+
spec.summary = 'Extensions to EventMachine/Synchrony to work well with exceptions'
|
7
|
+
spec.description = %q{}
|
8
|
+
spec.authors = ['Invoca']
|
9
|
+
spec.email = 'development@invoca.com'
|
10
|
+
spec.homepage = 'https://github.com/Invoca/exceptional_synchrony'
|
11
|
+
spec.license = 'MIT'
|
12
|
+
spec.files = `git ls-files`.split($/)
|
13
|
+
spec.version = ExceptionalSynchrony::VERSION
|
14
|
+
spec.metadata = {
|
15
|
+
"source_code_uri" => "https://github.com/Invoca/exceptional_synchrony",
|
16
|
+
"allowed_push_host" => "https://rubygems.org"
|
17
|
+
}
|
14
18
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
gem.add_development_dependency 'thor'
|
22
|
-
gem.add_development_dependency 'minitest'
|
23
|
-
gem.add_development_dependency 'webmock', '~> 1.17.1'
|
24
|
-
|
25
|
-
gem.add_development_dependency 'rr', '~> 1.1.2'
|
19
|
+
spec.add_dependency 'em-synchrony'
|
20
|
+
spec.add_dependency 'em-http-request'
|
21
|
+
spec.add_dependency 'eventmachine'
|
22
|
+
spec.add_dependency 'exception_handling', '~> 2.2'
|
23
|
+
spec.add_dependency 'invoca-utils', '~> 0.3'
|
26
24
|
end
|
@@ -21,13 +21,13 @@ module ExceptionalSynchrony
|
|
21
21
|
result
|
22
22
|
end
|
23
23
|
when :failed
|
24
|
-
if result.respond_to?(:error)
|
25
|
-
|
24
|
+
if result.respond_to?(:error)
|
25
|
+
handle_result_error(result)
|
26
26
|
else
|
27
|
-
|
27
|
+
raise_failure_for_result(result)
|
28
28
|
end
|
29
29
|
else
|
30
|
-
raise ArgumentError, "No deferred status set yet: #{deferred_status.inspect} #{result
|
30
|
+
raise ArgumentError, "No deferred status set yet: #{deferred_status.inspect} #{truncated_inspect(result)}"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -38,6 +38,38 @@ module ExceptionalSynchrony
|
|
38
38
|
ex
|
39
39
|
end
|
40
40
|
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def handle_result_error(result)
|
45
|
+
error = result.error
|
46
|
+
if error_is_a_timeout?(error)
|
47
|
+
raise Timeout::Error
|
48
|
+
else
|
49
|
+
raise_failure_for_result(result, error: error)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def raise_failure_for_result(result, error: nil)
|
54
|
+
result_string = truncated_inspect(result)
|
55
|
+
error_string = if error
|
56
|
+
"ERROR = #{truncated_inspect(error)}; "
|
57
|
+
end
|
58
|
+
raise Failure, "#{error_string}RESULT = #{result_string}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def truncated_inspect(obj)
|
62
|
+
inspection = obj.inspect[0, 101]
|
63
|
+
if inspection.length > 100
|
64
|
+
inspection[0, 92] + '...TRUNC'
|
65
|
+
else
|
66
|
+
inspection
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def error_is_a_timeout?(error)
|
71
|
+
error =~ /timeout/i || error == Errno::ETIMEDOUT
|
72
|
+
end
|
41
73
|
end
|
42
74
|
end
|
43
75
|
end
|
@@ -41,6 +41,12 @@ module ExceptionalSynchrony
|
|
41
41
|
@synchrony.sleep(seconds)
|
42
42
|
end
|
43
43
|
|
44
|
+
def yield_to_reactor
|
45
|
+
if reactor_running?
|
46
|
+
@synchrony.sleep(0)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
44
50
|
def next_tick(&block)
|
45
51
|
@synchrony.next_tick do
|
46
52
|
ensure_completely_safe("next_tick") do
|
@@ -68,6 +74,18 @@ module ExceptionalSynchrony
|
|
68
74
|
end
|
69
75
|
end
|
70
76
|
|
77
|
+
def defer(context, &block)
|
78
|
+
deferrable = EventMachine::DefaultDeferrable.new
|
79
|
+
|
80
|
+
callback = -> (result) { deferrable.succeed(result) }
|
81
|
+
|
82
|
+
EventMachine.defer(nil, callback) { CallbackExceptions.return_exception(&block) }
|
83
|
+
|
84
|
+
EventMachine::Synchrony.sync(deferrable)
|
85
|
+
|
86
|
+
CallbackExceptions.map_deferred_result(deferrable)
|
87
|
+
end
|
88
|
+
|
71
89
|
def reactor_running?
|
72
90
|
@proxy_class.reactor_running?
|
73
91
|
end
|
@@ -1,15 +1,17 @@
|
|
1
1
|
module ExceptionalSynchrony
|
2
2
|
class LimitedWorkQueue
|
3
|
+
|
3
4
|
def initialize(em, limit)
|
4
5
|
@em = em
|
5
6
|
limit > 0 or raise ArgumentError, "limit must be positive"
|
6
7
|
@limit = limit
|
7
8
|
@worker_count = 0
|
8
9
|
@job_procs = []
|
10
|
+
@paused = false
|
9
11
|
end
|
10
12
|
|
11
13
|
# Adds a job_proc to work.
|
12
|
-
def add(proc = nil, &block)
|
14
|
+
def add!(proc = nil, &block)
|
13
15
|
job = proc || block
|
14
16
|
job.respond_to?(:call) or raise "Must respond_to?(:call)! #{job.inspect}"
|
15
17
|
if @job_procs.any? && job.respond_to?(:merge) && (merged_queue = job.merge(@job_procs))
|
@@ -17,8 +19,9 @@ module ExceptionalSynchrony
|
|
17
19
|
else
|
18
20
|
@job_procs << job
|
19
21
|
end
|
20
|
-
work!
|
22
|
+
work! unless paused?
|
21
23
|
end
|
24
|
+
alias_method :add, :add!
|
22
25
|
|
23
26
|
def workers_empty?
|
24
27
|
@worker_count.zero?
|
@@ -32,18 +35,39 @@ module ExceptionalSynchrony
|
|
32
35
|
@job_procs.empty?
|
33
36
|
end
|
34
37
|
|
35
|
-
|
38
|
+
def paused?
|
39
|
+
@paused
|
40
|
+
end
|
41
|
+
|
42
|
+
def pause!
|
43
|
+
@paused = true
|
44
|
+
end
|
45
|
+
|
46
|
+
def unpause!
|
47
|
+
@paused = false
|
48
|
+
end
|
49
|
+
|
50
|
+
def items
|
51
|
+
@job_procs
|
52
|
+
end
|
53
|
+
|
36
54
|
def work!
|
37
55
|
until queue_empty? || workers_full?
|
38
56
|
job_proc = @job_procs.shift
|
39
57
|
@worker_count += 1
|
40
58
|
Fiber.new do
|
41
|
-
|
42
|
-
|
59
|
+
begin
|
60
|
+
job_proc.call
|
61
|
+
rescue => ex
|
62
|
+
ExceptionHandling.log_error(ex, "LimitedWorkQueue encountered an exception")
|
63
|
+
ensure
|
64
|
+
worker_done
|
65
|
+
end
|
43
66
|
end.resume
|
44
67
|
end
|
45
68
|
end
|
46
69
|
|
70
|
+
private
|
47
71
|
def worker_done
|
48
72
|
@worker_count -= 1
|
49
73
|
work!
|
data/test/test_helper.rb
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
ENV['RACK_ENV'] = 'test'
|
2
|
+
|
3
|
+
require 'bundler'
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
|
1
6
|
require_relative '../lib/exceptional_synchrony.rb'
|
2
7
|
|
3
8
|
require 'minitest/autorun' or raise "Already loaded minitest?"
|
@@ -6,6 +11,8 @@ require 'webmock'
|
|
6
11
|
require 'webmock/minitest'
|
7
12
|
require 'rr'
|
8
13
|
|
14
|
+
ActiveSupport::TestCase.test_order = :sorted
|
15
|
+
|
9
16
|
module TestHelper
|
10
17
|
@@constant_overrides = []
|
11
18
|
|