exceptional_synchrony 1.2.0 → 1.4.0.pre.2
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 +4 -4
- data/CHANGELOG.md +13 -3
- data/Gemfile.lock +37 -35
- data/Rakefile +1 -0
- data/lib/exceptional_synchrony/event_machine_proxy.rb +32 -10
- data/lib/exceptional_synchrony/version.rb +1 -1
- data/test/unit/event_machine_proxy_test.rb +71 -4
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7337c98f6e124b7e27327707ad7996bea893fe5c005ae57627e855ec35c77ff4
|
|
4
|
+
data.tar.gz: 2603dc05990ab4c3f257409382f8fc6453f8e22446a82a1ad9841564b509994e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bd0b2894a70161f7162c465aacf315cada6748267d88590bb943d3c68ad382f0ed1b910224738f54b1a1ada219f894b9fd64bcb2f06c7f3b95f0c9b3efb1d218
|
|
7
|
+
data.tar.gz: b9b7c5fde46b71d32651108b855f4396517e32a73915b1e3bc09e258a5bcee678d3946ca3fc6c768eef1deebc0edaa66e4e41898b3a08a6d95e993c0bc12339e
|
data/CHANGELOG.md
CHANGED
|
@@ -5,10 +5,15 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
5
5
|
Note: This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
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
8
|
|
|
11
|
-
[1.
|
|
9
|
+
## [1.4.0] - UNRELEASED
|
|
10
|
+
### Added
|
|
11
|
+
- Added `:faraday_adapter` option to `EventMachineProxy#run` with a default of `:em_synchrony`
|
|
12
|
+
so that the reactor does not get blocked when using `Faraday` connections
|
|
13
|
+
|
|
14
|
+
## [1.3.0] - 2021-02-04
|
|
15
|
+
### Added
|
|
16
|
+
- Extend `EMP.defer` to have a new keyword argument, `wait_for_result` for the callers to control whether they should should block until the background thread returns. To preserve existing behavior, this option defaults to `true`, so `EMP.defer` will block in order to return the value (or raise an exception) from the deferred block. Callers can pass `wait_for_result: false` if they do not want to block.
|
|
12
17
|
|
|
13
18
|
## [1.2.0] - 2020-06-02
|
|
14
19
|
### Changed
|
|
@@ -21,4 +26,9 @@ All notable changes to this project will be documented in this file.
|
|
|
21
26
|
We expect that outer edge handler to log the exception chain (the wrapper plus nested `cause` exception(s))
|
|
22
27
|
and exit the process with a non-0 status code.
|
|
23
28
|
|
|
29
|
+
## [1.1.1] - 2020-05-03
|
|
30
|
+
- Replace hobo_support with invoca_utils
|
|
31
|
+
|
|
32
|
+
[1.3.0]: https://github.com/Invoca/exceptional_synchrony/compare/v1.2.0...v1.3.0
|
|
24
33
|
[1.2.0]: https://github.com/Invoca/exceptional_synchrony/compare/v1.1.1...v1.2.0
|
|
34
|
+
[1.1.1]: https://github.com/Invoca/exceptional_synchrony/compare/v1.1.0...v1.1.1
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
exceptional_synchrony (1.
|
|
4
|
+
exceptional_synchrony (1.4.0.pre.2)
|
|
5
5
|
em-http-request
|
|
6
6
|
em-synchrony
|
|
7
7
|
eventmachine
|
|
@@ -11,48 +11,49 @@ PATH
|
|
|
11
11
|
GEM
|
|
12
12
|
remote: https://rubygems.org/
|
|
13
13
|
specs:
|
|
14
|
-
actionmailer (6.
|
|
15
|
-
actionpack (= 6.
|
|
16
|
-
actionview (= 6.
|
|
17
|
-
activejob (= 6.
|
|
14
|
+
actionmailer (6.1.1)
|
|
15
|
+
actionpack (= 6.1.1)
|
|
16
|
+
actionview (= 6.1.1)
|
|
17
|
+
activejob (= 6.1.1)
|
|
18
|
+
activesupport (= 6.1.1)
|
|
18
19
|
mail (~> 2.5, >= 2.5.4)
|
|
19
20
|
rails-dom-testing (~> 2.0)
|
|
20
|
-
actionpack (6.
|
|
21
|
-
actionview (= 6.
|
|
22
|
-
activesupport (= 6.
|
|
23
|
-
rack (~> 2.0, >= 2.0.
|
|
21
|
+
actionpack (6.1.1)
|
|
22
|
+
actionview (= 6.1.1)
|
|
23
|
+
activesupport (= 6.1.1)
|
|
24
|
+
rack (~> 2.0, >= 2.0.9)
|
|
24
25
|
rack-test (>= 0.6.3)
|
|
25
26
|
rails-dom-testing (~> 2.0)
|
|
26
27
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
|
27
|
-
actionview (6.
|
|
28
|
-
activesupport (= 6.
|
|
28
|
+
actionview (6.1.1)
|
|
29
|
+
activesupport (= 6.1.1)
|
|
29
30
|
builder (~> 3.1)
|
|
30
31
|
erubi (~> 1.4)
|
|
31
32
|
rails-dom-testing (~> 2.0)
|
|
32
33
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
|
33
|
-
activejob (6.
|
|
34
|
-
activesupport (= 6.
|
|
34
|
+
activejob (6.1.1)
|
|
35
|
+
activesupport (= 6.1.1)
|
|
35
36
|
globalid (>= 0.3.6)
|
|
36
|
-
activesupport (6.
|
|
37
|
+
activesupport (6.1.1)
|
|
37
38
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
38
|
-
i18n (>=
|
|
39
|
-
minitest (
|
|
40
|
-
tzinfo (~>
|
|
41
|
-
zeitwerk (~> 2.
|
|
39
|
+
i18n (>= 1.6, < 2)
|
|
40
|
+
minitest (>= 5.1)
|
|
41
|
+
tzinfo (~> 2.0)
|
|
42
|
+
zeitwerk (~> 2.3)
|
|
42
43
|
addressable (2.7.0)
|
|
43
44
|
public_suffix (>= 2.0.2, < 5.0)
|
|
44
45
|
ansi (1.5.0)
|
|
45
46
|
builder (3.2.4)
|
|
46
47
|
coderay (1.1.2)
|
|
47
|
-
concurrent-ruby (1.1.
|
|
48
|
-
contextual_logger (0.
|
|
48
|
+
concurrent-ruby (1.1.8)
|
|
49
|
+
contextual_logger (0.11.0)
|
|
49
50
|
activesupport
|
|
50
51
|
json
|
|
51
52
|
cookiejar (0.3.3)
|
|
52
53
|
crack (0.4.3)
|
|
53
54
|
safe_yaml (~> 1.0.0)
|
|
54
55
|
crass (1.0.6)
|
|
55
|
-
em-http-request (1.1.
|
|
56
|
+
em-http-request (1.1.7)
|
|
56
57
|
addressable (>= 2.3.4)
|
|
57
58
|
cookiejar (!= 0.3.1)
|
|
58
59
|
em-socksify (>= 0.3)
|
|
@@ -62,9 +63,9 @@ GEM
|
|
|
62
63
|
eventmachine (>= 1.0.0.beta.4)
|
|
63
64
|
em-synchrony (1.0.6)
|
|
64
65
|
eventmachine (>= 1.0.0.beta.1)
|
|
65
|
-
erubi (1.
|
|
66
|
+
erubi (1.10.0)
|
|
66
67
|
eventmachine (1.2.7)
|
|
67
|
-
exception_handling (2.
|
|
68
|
+
exception_handling (2.8.1)
|
|
68
69
|
actionmailer (>= 4.2, < 7.0)
|
|
69
70
|
actionpack (>= 4.2, < 7.0)
|
|
70
71
|
activesupport (>= 4.2, < 7.0)
|
|
@@ -75,31 +76,33 @@ GEM
|
|
|
75
76
|
activesupport (>= 4.2.0)
|
|
76
77
|
hashdiff (1.0.1)
|
|
77
78
|
http_parser.rb (0.6.0)
|
|
78
|
-
i18n (1.8.
|
|
79
|
+
i18n (1.8.8)
|
|
79
80
|
concurrent-ruby (~> 1.0)
|
|
80
|
-
invoca-utils (0.
|
|
81
|
-
json (2.
|
|
82
|
-
loofah (2.
|
|
81
|
+
invoca-utils (0.4.1)
|
|
82
|
+
json (2.5.1)
|
|
83
|
+
loofah (2.9.0)
|
|
83
84
|
crass (~> 1.0.2)
|
|
84
85
|
nokogiri (>= 1.5.9)
|
|
85
86
|
mail (2.7.1)
|
|
86
87
|
mini_mime (>= 0.1.1)
|
|
87
88
|
method_source (1.0.0)
|
|
88
89
|
mini_mime (1.0.2)
|
|
89
|
-
mini_portile2 (2.
|
|
90
|
+
mini_portile2 (2.5.0)
|
|
90
91
|
minitest (5.14.0)
|
|
91
92
|
minitest-reporters (1.4.2)
|
|
92
93
|
ansi
|
|
93
94
|
builder
|
|
94
95
|
minitest (>= 5.0)
|
|
95
96
|
ruby-progressbar
|
|
96
|
-
nokogiri (1.
|
|
97
|
-
mini_portile2 (~> 2.
|
|
97
|
+
nokogiri (1.11.1)
|
|
98
|
+
mini_portile2 (~> 2.5.0)
|
|
99
|
+
racc (~> 1.4)
|
|
98
100
|
pry (0.13.1)
|
|
99
101
|
coderay (~> 1.1)
|
|
100
102
|
method_source (~> 1.0)
|
|
101
103
|
public_suffix (4.0.4)
|
|
102
|
-
|
|
104
|
+
racc (1.5.2)
|
|
105
|
+
rack (2.2.3)
|
|
103
106
|
rack-test (1.1.0)
|
|
104
107
|
rack (>= 1.0, < 3)
|
|
105
108
|
rails-dom-testing (2.0.3)
|
|
@@ -112,14 +115,13 @@ GEM
|
|
|
112
115
|
ruby-progressbar (1.10.1)
|
|
113
116
|
safe_yaml (1.0.5)
|
|
114
117
|
thor (1.0.1)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
thread_safe (~> 0.1)
|
|
118
|
+
tzinfo (2.0.4)
|
|
119
|
+
concurrent-ruby (~> 1.0)
|
|
118
120
|
webmock (1.24.6)
|
|
119
121
|
addressable (>= 2.3.6)
|
|
120
122
|
crack (>= 0.3.2)
|
|
121
123
|
hashdiff
|
|
122
|
-
zeitwerk (2.
|
|
124
|
+
zeitwerk (2.4.2)
|
|
123
125
|
|
|
124
126
|
PLATFORMS
|
|
125
127
|
ruby
|
data/Rakefile
CHANGED
|
@@ -64,14 +64,24 @@ module ExceptionalSynchrony
|
|
|
64
64
|
@proxy_class.next_tick { } #Fake out EventMachine's epoll mechanism so we don't block until timers fire
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
+
def defers_finished?
|
|
68
|
+
@proxy_class.defers_finished?
|
|
69
|
+
end
|
|
70
|
+
|
|
67
71
|
def connect(server, port = nil, handler = nil, *args, &block)
|
|
68
72
|
@proxy_class.connect(server, port, handler, *args, &block)
|
|
69
73
|
end
|
|
70
74
|
|
|
75
|
+
# This method starts the EventMachine reactor.
|
|
71
76
|
# The on_error option has these possible values:
|
|
72
77
|
# :log - log any rescued StandardError exceptions and continue
|
|
73
78
|
# :raise - raise FatalRunError for any rescued StandardError exceptions
|
|
74
|
-
|
|
79
|
+
# The faraday_adapter option has these possible values that only apply if Faraday connections are in use:
|
|
80
|
+
# :em_synchrony - for use when EM::Synchrony is being used in all threads of the given process
|
|
81
|
+
# :net_http - for use when EM::Synchrony is being used in only some threads of the given process;
|
|
82
|
+
# in this case requests made over the Faraday connection will block the reactor
|
|
83
|
+
def run(on_error: :log, faraday_adapter: :em_synchrony, &block)
|
|
84
|
+
configure_faraday(faraday_adapter)
|
|
75
85
|
case on_error
|
|
76
86
|
when :log then run_with_error_logging(&block)
|
|
77
87
|
when :raise then run_with_error_raising(&block)
|
|
@@ -79,16 +89,21 @@ module ExceptionalSynchrony
|
|
|
79
89
|
end
|
|
80
90
|
end
|
|
81
91
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
EventMachine::Synchrony.sync(deferrable)
|
|
92
|
+
# This method will execute the block on the background thread pool
|
|
93
|
+
# By default, it will block the caller until the background thread has finished, so that the result can be returned
|
|
94
|
+
# :wait_for_result - setting this to false will prevent the caller from being blocked by this deferred work
|
|
95
|
+
def defer(context, wait_for_result: true, &block)
|
|
96
|
+
if wait_for_result
|
|
97
|
+
deferrable = EventMachine::DefaultDeferrable.new
|
|
98
|
+
callback = -> (result) { deferrable.succeed(result) }
|
|
90
99
|
|
|
91
|
-
|
|
100
|
+
EventMachine.defer(nil, callback) { CallbackExceptions.return_exception(&block) }
|
|
101
|
+
EventMachine::Synchrony.sync(deferrable)
|
|
102
|
+
CallbackExceptions.map_deferred_result(deferrable)
|
|
103
|
+
else
|
|
104
|
+
EventMachine.defer { ExceptionHandling.ensure_completely_safe("defer", &block) }
|
|
105
|
+
nil
|
|
106
|
+
end
|
|
92
107
|
end
|
|
93
108
|
|
|
94
109
|
def reactor_running?
|
|
@@ -124,6 +139,13 @@ module ExceptionalSynchrony
|
|
|
124
139
|
|
|
125
140
|
private
|
|
126
141
|
|
|
142
|
+
def configure_faraday(adapter)
|
|
143
|
+
if defined?(Faraday)
|
|
144
|
+
adapter.in?([:em_synchrony, :net_http]) or raise ArgumentError, "Invalid faraday_adapter: #{adapter.inspect}"
|
|
145
|
+
Faraday.default_adapter = adapter
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
127
149
|
def run_with_error_logging(&block)
|
|
128
150
|
ensure_completely_safe("run_with_error_logging") do
|
|
129
151
|
if @proxy_class.respond_to?(:synchrony)
|
|
@@ -24,6 +24,14 @@ describe ExceptionalSynchrony::EventMachineProxy do
|
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
def stop_em_after_defers_finish!(em)
|
|
28
|
+
check_finished_counter = 0
|
|
29
|
+
em.add_periodic_timer(0.1) do
|
|
30
|
+
(check_finished_counter += 1) > 20 and raise "defer never finished!"
|
|
31
|
+
em.defers_finished? and em.stop
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
27
35
|
before do
|
|
28
36
|
@em = ExceptionalSynchrony::EventMachineProxy.new(EventMachine, nil)
|
|
29
37
|
@yielded_value = nil
|
|
@@ -78,18 +86,41 @@ describe ExceptionalSynchrony::EventMachineProxy do
|
|
|
78
86
|
end
|
|
79
87
|
|
|
80
88
|
describe "#defer" do
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
before do
|
|
90
|
+
logger = Logger.new(STDERR)
|
|
91
|
+
logger.extend ContextualLogger::LoggerMixin
|
|
92
|
+
ExceptionHandling.logger = logger
|
|
93
|
+
end
|
|
83
94
|
|
|
95
|
+
it "should output its block's output when it doesn't raise an error, by default" do
|
|
84
96
|
@em.run do
|
|
85
97
|
assert_equal 12, @em.defer("#defer success") { 12 }
|
|
86
98
|
@em.stop
|
|
87
99
|
end
|
|
88
100
|
end
|
|
89
101
|
|
|
90
|
-
it "should
|
|
91
|
-
|
|
102
|
+
it "should not wait for its block to run if option is passed" do
|
|
103
|
+
@block_ran = false
|
|
104
|
+
|
|
105
|
+
@em.run do
|
|
106
|
+
assert_nil @em.defer("#defer success", wait_for_result: false) { @block_ran = true; 12 }
|
|
107
|
+
refute @block_ran
|
|
108
|
+
stop_em_after_defers_finish!(@em)
|
|
109
|
+
end
|
|
92
110
|
|
|
111
|
+
assert @block_ran
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "should handle exceptions when not waiting for its block to run" do
|
|
115
|
+
mock(ExceptionHandling).log_error(is_a(RuntimeError), "defer", {})
|
|
116
|
+
|
|
117
|
+
@em.run do
|
|
118
|
+
assert_nil @em.defer("#defer success", wait_for_result: false) { raise RuntimeError, "error in defer" }
|
|
119
|
+
stop_em_after_defers_finish!(@em)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should raise an error when its block raises an error" do
|
|
93
124
|
@em.run do
|
|
94
125
|
ex = assert_raises(ArgumentError) do
|
|
95
126
|
@em.defer("#defer raising an error") { raise ArgumentError, "!!!" }
|
|
@@ -127,6 +158,42 @@ describe ExceptionalSynchrony::EventMachineProxy do
|
|
|
127
158
|
end
|
|
128
159
|
end
|
|
129
160
|
|
|
161
|
+
describe "run with faraday" do
|
|
162
|
+
before do
|
|
163
|
+
class Faraday
|
|
164
|
+
class << self
|
|
165
|
+
attr_reader :default_adapter
|
|
166
|
+
|
|
167
|
+
def default_adapter=(adapter)
|
|
168
|
+
@default_adapter = adapter
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
self.default_adapter = :net_http
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
assert_equal :net_http, Faraday.default_adapter
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "sets Faraday default_adapter to :em_synchrony by default if Faraday is defined" do
|
|
179
|
+
mock(@em).run_with_error_logging
|
|
180
|
+
@em.run
|
|
181
|
+
assert_equal :em_synchrony, Faraday.default_adapter
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "sets Faraday default_adapter to :net_http if Faraday is defined" do
|
|
185
|
+
mock(@em).run_with_error_logging
|
|
186
|
+
@em.run(faraday_adapter: :net_http)
|
|
187
|
+
assert_equal :net_http, Faraday.default_adapter
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it "raise ArgumentError if the specified faraday_adapter is invalid" do
|
|
191
|
+
assert_raises(ArgumentError, "Invalid faraday_adapter: :bogus") do
|
|
192
|
+
@em.run(faraday_adapter: :bogus)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
130
197
|
{ synchrony: SynchronyProxyMock, run: RunProxyMock }.each do |method, proxy_mock|
|
|
131
198
|
describe "run" do
|
|
132
199
|
before do
|
metadata
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: exceptional_synchrony
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0.pre.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Invoca
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
date: 2014-01-16 00:00:00.000000000 Z
|
|
@@ -115,7 +115,7 @@ licenses:
|
|
|
115
115
|
metadata:
|
|
116
116
|
source_code_uri: https://github.com/Invoca/exceptional_synchrony
|
|
117
117
|
allowed_push_host: https://rubygems.org
|
|
118
|
-
post_install_message:
|
|
118
|
+
post_install_message:
|
|
119
119
|
rdoc_options: []
|
|
120
120
|
require_paths:
|
|
121
121
|
- lib
|
|
@@ -126,12 +126,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
126
126
|
version: '0'
|
|
127
127
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
128
|
requirements:
|
|
129
|
-
- - "
|
|
129
|
+
- - ">"
|
|
130
130
|
- !ruby/object:Gem::Version
|
|
131
|
-
version:
|
|
131
|
+
version: 1.3.1
|
|
132
132
|
requirements: []
|
|
133
133
|
rubygems_version: 3.0.3
|
|
134
|
-
signing_key:
|
|
134
|
+
signing_key:
|
|
135
135
|
specification_version: 4
|
|
136
136
|
summary: Extensions to EventMachine/Synchrony to work well with exceptions
|
|
137
137
|
test_files: []
|