exceptional_synchrony 1.2.0 → 1.4.0.pre.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f13da539398611f0cfabb6439072114ef3904d89028205ee79bd7c17cb439ca
4
- data.tar.gz: 1089857cd4e512dd3717b403163a3f74d53bc2cf0902bd13890fb842c7a9644b
3
+ metadata.gz: 7337c98f6e124b7e27327707ad7996bea893fe5c005ae57627e855ec35c77ff4
4
+ data.tar.gz: 2603dc05990ab4c3f257409382f8fc6453f8e22446a82a1ad9841564b509994e
5
5
  SHA512:
6
- metadata.gz: bb0ce260721a479fe42118cfe78c5e06a45e36801e7d3cc25eb823baeff7693c46071bb07e314e3f51aad2b5ed3d61373219c1015b2f9cc0ff28bd1a116f8bb7
7
- data.tar.gz: 81ed89b82782b3f80494b999efeb3d629834c1a4ab1e9e31ab446e4e7a58da0d915252e6f3e401945e1f2be82c20bc3d1f59e34667805180199ee0c2758f91fd
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.1.1]: https://github.com/Invoca/exceptional_synchrony/compare/v1.1.0...v1.1.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.2.0)
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.0.3.1)
15
- actionpack (= 6.0.3.1)
16
- actionview (= 6.0.3.1)
17
- activejob (= 6.0.3.1)
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.0.3.1)
21
- actionview (= 6.0.3.1)
22
- activesupport (= 6.0.3.1)
23
- rack (~> 2.0, >= 2.0.8)
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.0.3.1)
28
- activesupport (= 6.0.3.1)
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.0.3.1)
34
- activesupport (= 6.0.3.1)
34
+ activejob (6.1.1)
35
+ activesupport (= 6.1.1)
35
36
  globalid (>= 0.3.6)
36
- activesupport (6.0.3.1)
37
+ activesupport (6.1.1)
37
38
  concurrent-ruby (~> 1.0, >= 1.0.2)
38
- i18n (>= 0.7, < 2)
39
- minitest (~> 5.1)
40
- tzinfo (~> 1.1)
41
- zeitwerk (~> 2.2, >= 2.2.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.6)
48
- contextual_logger (0.8.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.5)
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.9.0)
66
+ erubi (1.10.0)
66
67
  eventmachine (1.2.7)
67
- exception_handling (2.4.3)
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.2)
79
+ i18n (1.8.8)
79
80
  concurrent-ruby (~> 1.0)
80
- invoca-utils (0.3.0)
81
- json (2.3.0)
82
- loofah (2.5.0)
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.4.0)
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.10.9)
97
- mini_portile2 (~> 2.4.0)
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
- rack (2.2.2)
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
- thread_safe (0.3.6)
116
- tzinfo (1.2.7)
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.3.0)
124
+ zeitwerk (2.4.2)
123
125
 
124
126
  PLATFORMS
125
127
  ruby
data/Rakefile CHANGED
@@ -7,6 +7,7 @@ require 'rake/testtask'
7
7
  task default: :test
8
8
 
9
9
  Rake::TestTask.new do |t|
10
+ t.warning = false
10
11
  t.pattern = "test/**/*_test.rb"
11
12
  end
12
13
 
@@ -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
- def run(on_error: :log, &block)
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
- def defer(context, &block)
83
- deferrable = EventMachine::DefaultDeferrable.new
84
-
85
- callback = -> (result) { deferrable.succeed(result) }
86
-
87
- EventMachine.defer(nil, callback) { CallbackExceptions.return_exception(&block) }
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
- CallbackExceptions.map_deferred_result(deferrable)
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)
@@ -1,3 +1,3 @@
1
1
  module ExceptionalSynchrony
2
- VERSION = '1.2.0'
2
+ VERSION = '1.4.0.pre.2'
3
3
  end
@@ -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
- it "should output its block's output when it doesn't raise an error" do
82
- ExceptionHandling.logger = Logger.new(STDERR)
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 raise an error when its block raises an error" do
91
- ExceptionHandling.logger = Logger.new(STDERR)
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.2.0
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: '0'
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: []