exceptional_synchrony 1.3.0.pre.lee.1 → 1.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d50d71b944ece103dd43d1efb29002bacec564abcab11ff3bf2b2f3d39cf68f8
4
- data.tar.gz: 54222d22252ea445f8ae8eab5cca785cded326979ca9665619c12873bef0819f
3
+ metadata.gz: d067a2b3a9635740dbee2374a06e772c29ca9a8fe57a61108c94118ac15480bb
4
+ data.tar.gz: 665f4bf8ccc1ea699c0d56a4f7d38647c2e3e64e814b736562bf83b69ccd0d25
5
5
  SHA512:
6
- metadata.gz: ac56deba463c441e282cf315866941bdfe5f399c0605e23778fb155960a7b5f469fdbc9e378fa3a72cb833102f528698148a7fe58d3df30effc46e51648bd3b8
7
- data.tar.gz: 4edd6057dcab5bb74334ec97cc95e02f27da421e89e56a8c78383f6103a12fc3a0a85048e06626839ebe97bc8b50c65981542c90518d5937eb6553d9aca24d65
6
+ metadata.gz: 9961b1ef53acfb4c94651611871b120279dab3b3564e1841b199a7b2fa1f7a3728bca945517f50964704b0491f9a086192cb857a3205c6008758ecb51a4fb9c5
7
+ data.tar.gz: 0a4d64204faf45276aaca59757ad43bb850c75ea668671e92eae251721a19c6b2ce0ecae5b3bb38c8a64179ba41d0b0864bf1a6640de4e234c4c772434bcfca0
data/CHANGELOG.md CHANGED
@@ -6,15 +6,9 @@ Note: This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0
6
6
 
7
7
  All notable changes to this project will be documented in this file.
8
8
 
9
- ## [1.3.0] - UNRELEASED
9
+ ## [1.3.0] - 2021-02-04
10
10
  ### Added
11
- - For users of `Faraday` connections, its `default_adapter` is configured to `:em_synchrony` when starting
12
- the `EventMachine` reactor so that the reactor does not get blocked when using `Faraday`
13
-
14
- ## [1.1.1] - 2020-05-03
15
- - Replace hobo_support with invoca_utils
16
-
17
- [1.1.1]: https://github.com/Invoca/exceptional_synchrony/compare/v1.1.0...v1.1.1
11
+ - 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.
18
12
 
19
13
  ## [1.2.0] - 2020-06-02
20
14
  ### Changed
@@ -27,4 +21,9 @@ All notable changes to this project will be documented in this file.
27
21
  We expect that outer edge handler to log the exception chain (the wrapper plus nested `cause` exception(s))
28
22
  and exit the process with a non-0 status code.
29
23
 
24
+ ## [1.1.1] - 2020-05-03
25
+ - Replace hobo_support with invoca_utils
26
+
27
+ [1.3.0]: https://github.com/Invoca/exceptional_synchrony/compare/v1.2.0...v1.3.0
30
28
  [1.2.0]: https://github.com/Invoca/exceptional_synchrony/compare/v1.1.1...v1.2.0
29
+ [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.3.0.pre.lee.1)
4
+ exceptional_synchrony (1.3.0)
5
5
  em-http-request
6
6
  em-synchrony
7
7
  eventmachine
@@ -76,7 +76,7 @@ GEM
76
76
  activesupport (>= 4.2.0)
77
77
  hashdiff (1.0.1)
78
78
  http_parser.rb (0.6.0)
79
- i18n (1.8.8)
79
+ i18n (1.8.7)
80
80
  concurrent-ruby (~> 1.0)
81
81
  invoca-utils (0.4.1)
82
82
  json (2.5.1)
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,6 +64,10 @@ 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
@@ -72,7 +76,6 @@ module ExceptionalSynchrony
72
76
  # :log - log any rescued StandardError exceptions and continue
73
77
  # :raise - raise FatalRunError for any rescued StandardError exceptions
74
78
  def run(on_error: :log, &block)
75
- configure_faraday
76
79
  case on_error
77
80
  when :log then run_with_error_logging(&block)
78
81
  when :raise then run_with_error_raising(&block)
@@ -80,16 +83,21 @@ module ExceptionalSynchrony
80
83
  end
81
84
  end
82
85
 
83
- def defer(context, &block)
84
- deferrable = EventMachine::DefaultDeferrable.new
85
-
86
- callback = -> (result) { deferrable.succeed(result) }
87
-
88
- EventMachine.defer(nil, callback) { CallbackExceptions.return_exception(&block) }
89
-
90
- EventMachine::Synchrony.sync(deferrable)
86
+ # This method will execute the block on the background thread pool
87
+ # By default, it will block the caller until the background thread has finished, so that the result can be returned
88
+ # :wait_for_result - setting this to false will prevent the caller from being blocked by this deferred work
89
+ def defer(context, wait_for_result: true, &block)
90
+ if wait_for_result
91
+ deferrable = EventMachine::DefaultDeferrable.new
92
+ callback = -> (result) { deferrable.succeed(result) }
91
93
 
92
- CallbackExceptions.map_deferred_result(deferrable)
94
+ EventMachine.defer(nil, callback) { CallbackExceptions.return_exception(&block) }
95
+ EventMachine::Synchrony.sync(deferrable)
96
+ CallbackExceptions.map_deferred_result(deferrable)
97
+ else
98
+ EventMachine.defer { ExceptionHandling.ensure_completely_safe("defer", &block) }
99
+ nil
100
+ end
93
101
  end
94
102
 
95
103
  def reactor_running?
@@ -125,12 +133,6 @@ module ExceptionalSynchrony
125
133
 
126
134
  private
127
135
 
128
- def configure_faraday
129
- if defined?(Faraday)
130
- Faraday.default_adapter = :em_synchrony
131
- end
132
- end
133
-
134
136
  def run_with_error_logging(&block)
135
137
  ensure_completely_safe("run_with_error_logging") do
136
138
  if @proxy_class.respond_to?(:synchrony)
@@ -1,3 +1,3 @@
1
1
  module ExceptionalSynchrony
2
- VERSION = '1.3.0.pre.lee.1'
2
+ VERSION = '1.3.0'
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
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
92
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,27 +158,6 @@ describe ExceptionalSynchrony::EventMachineProxy do
127
158
  end
128
159
  end
129
160
 
130
- describe "run with faraday" do
131
- it "should conigure Faraday default_adapter to :em_synchrony if Faraday is defined" do
132
- class Faraday
133
- class << self
134
- attr_reader :default_adapter
135
-
136
- def default_adapter=(adapter)
137
- @default_adapter = adapter
138
- end
139
- end
140
-
141
- self.default_adapter = :net_http
142
- end
143
-
144
- mock(@em).run_with_error_logging
145
- assert_equal :net_http, Faraday.default_adapter
146
- @em.run
147
- assert_equal :em_synchrony, Faraday.default_adapter
148
- end
149
- end
150
-
151
161
  { synchrony: SynchronyProxyMock, run: RunProxyMock }.each do |method, proxy_mock|
152
162
  describe "run" do
153
163
  before do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exceptional_synchrony
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0.pre.lee.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Invoca
@@ -126,9 +126,9 @@ 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: 1.3.1
131
+ version: '0'
132
132
  requirements: []
133
133
  rubygems_version: 3.0.3
134
134
  signing_key: