exceptional_synchrony 1.1.1 → 1.4.0.pre.1

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: 883532dc8502a497eabb0785806a621f034463c021e676526ff70a5c4119d5c1
4
- data.tar.gz: 927c40e91113f1c0fb6828f400253c18fa6abcb1fec772327913a966a21fdc9c
3
+ metadata.gz: 23aa4209588ee0dc66a1c96e25d1a524e1191f7d6f46a0acdfae90c04f19bf93
4
+ data.tar.gz: 1c40477122edb3b80bdfae312e486ef8a85cf4bac2c9ee78793e6de97bd72b5e
5
5
  SHA512:
6
- metadata.gz: eb19bc5fbcdd191ef8ea84acb72fae37c8b32a042fccfa15de3e6b0b41d9f6fc5a7d3a4aa488da6d337e60bf6f1ca93b9e1ff948c3ed2e4f948b92b576fc1a76
7
- data.tar.gz: 9ea68a7d671a07e59a09b4cf56c99562db38b83decd54b7399e45a54e8f7ac7fedca70c5e20ab319b90a054dda758eed701497683b9b5f39f0fd52ee79c3b590
6
+ metadata.gz: 3fec9e8a041a72ee6c521d1ffb33eeef2a470c3df92b41dacaf7c57d6aa33fe0e3d2ee85392f68261c6ed00e29c0264f809dee303ba896bfc471682f161f2303
7
+ data.tar.gz: 04d48f19f25bcae51e5b97bf318f78c44151b3d3417dac6b536f25f7b2d778736de0b226aa80c540fbd14801c587c2ffd80e0f4c2890c2ef7003f46fb24f5add
data/.gitignore CHANGED
@@ -34,6 +34,7 @@ intermediate
34
34
  publish
35
35
  .bundle
36
36
  pkg/
37
+ test/reports
37
38
 
38
39
  # Vim
39
40
  *.s[a-w][a-z]
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/groovy
2
+ @Library('jenkins-pipeline@v0.4.5')
3
+ import com.invoca.docker.*;
4
+ pipeline {
5
+ agent {
6
+ kubernetes {
7
+ defaultContainer "ruby"
8
+ yamlFile ".jenkins/ruby_build_pod.yml"
9
+ }
10
+ }
11
+
12
+ environment {
13
+ GITHUB_TOKEN = credentials('github_token')
14
+ GITHUB_KEY = credentials('github_key')
15
+ BUNDLE_GEM__FURY__IO = credentials('gemfury_deploy_token')
16
+ }
17
+
18
+ stages {
19
+ stage('Setup') {
20
+ steps {
21
+ updateGitHubStatus('clean-build', 'pending', 'Unit tests.')
22
+ script {
23
+ sh '''
24
+ # get SSH setup inside the container
25
+ eval `ssh-agent -s`
26
+ echo "$GITHUB_KEY" | ssh-add -
27
+ mkdir -p /root/.ssh
28
+ ssh-keyscan -t rsa github.com > /root/.ssh/known_hosts
29
+ bundle install
30
+ ''' }
31
+ }
32
+ }
33
+ stage('Unit Test') {
34
+ steps {
35
+ script {
36
+ sh 'bundle exec rake'
37
+ }
38
+ }
39
+ post {
40
+ always { junit '*/reports/*.xml' }
41
+ success { updateGitHubStatus('clean-build', 'success', 'Unit tests.') }
42
+ failure { updateGitHubStatus('clean-build', 'failure', 'Unit tests.') }
43
+ }
44
+ }
45
+ }
46
+ }
47
+
48
+ void updateGitHubStatus(String context, String status, String description) {
49
+ gitHubStatus([
50
+ repoSlug: 'Invoca/exceptional_synchrony',
51
+ sha: env.GIT_COMMIT,
52
+ description: description,
53
+ context: context,
54
+ targetURL: env.RUN_DISPLAY_URL,
55
+ token: env.GITHUB_TOKEN,
56
+ status: status
57
+ ])
58
+ }
@@ -0,0 +1,19 @@
1
+ ---
2
+ apiVersion: v1
3
+ kind: Pod
4
+ metadata:
5
+ labels:
6
+ jenkins/exceptional-synchrony: 'true'
7
+ namespace: jenkins
8
+ name: exceptional-synchrony
9
+ spec:
10
+ containers:
11
+ - name: ruby
12
+ image: ruby:2.6.5
13
+ tty: true
14
+ resources:
15
+ requests:
16
+ memory: "100Mi"
17
+ command:
18
+ - cat
19
+
data/CHANGELOG.md CHANGED
@@ -1,11 +1,34 @@
1
- # CHANGELOG for `exceptional_synchrony`
1
+ # CHANGELOG for `exception_synchrony`
2
2
 
3
3
  Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
4
4
 
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
+
9
+ ## [1.4.0] - UNRELEASED
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.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.
17
+
18
+ ## [1.2.0] - 2020-06-02
19
+ ### Changed
20
+ - If `EMP.run` rescues an exception, previous versions would simply log the exception and continue.
21
+ Instead this version has an `on_error` option with possible values `:log` and `:raise`.
22
+ It defaults to `:log` and in that case, as before, logs any rescued `StandardError` exception and continues.
23
+ When `on_error` is set to `:raise`, the method raises a `FatalRunError` wrapper around the rescued exception.
24
+ This `FatalRunError` exception does not derive from `StandardError`, so it will not be erroneously rescued by any
25
+ registered `EMP.error_handler`. Instead it should be rescued at the outer edge of the process.
26
+ We expect that outer edge handler to log the exception chain (the wrapper plus nested `cause` exception(s))
27
+ and exit the process with a non-0 status code.
28
+
8
29
  ## [1.1.1] - 2020-05-03
9
30
  - Replace hobo_support with invoca_utils
10
31
 
32
+ [1.3.0]: https://github.com/Invoca/exceptional_synchrony/compare/v1.2.0...v1.3.0
33
+ [1.2.0]: https://github.com/Invoca/exceptional_synchrony/compare/v1.1.1...v1.2.0
11
34
  [1.1.1]: https://github.com/Invoca/exceptional_synchrony/compare/v1.1.0...v1.1.1
data/Gemfile CHANGED
@@ -7,6 +7,7 @@ gemspec
7
7
 
8
8
  group :development do
9
9
  gem 'minitest'
10
+ gem 'minitest-reporters'
10
11
  gem 'pry'
11
12
  gem 'rake'
12
13
  gem 'rr', '~> 1.2'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- exceptional_synchrony (1.1.1)
4
+ exceptional_synchrony (1.4.0.pre.1)
5
5
  em-http-request
6
6
  em-synchrony
7
7
  eventmachine
@@ -11,46 +11,49 @@ PATH
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- actionmailer (4.2.11.1)
15
- actionpack (= 4.2.11.1)
16
- actionview (= 4.2.11.1)
17
- activejob (= 4.2.11.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
- 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)
20
+ rails-dom-testing (~> 2.0)
21
+ actionpack (6.1.1)
22
+ actionview (= 6.1.1)
23
+ activesupport (= 6.1.1)
24
+ rack (~> 2.0, >= 2.0.9)
25
+ rack-test (>= 0.6.3)
26
+ rails-dom-testing (~> 2.0)
27
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
28
+ actionview (6.1.1)
29
+ activesupport (= 6.1.1)
29
30
  builder (~> 3.1)
30
- erubis (~> 2.7.0)
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)
31
+ erubi (~> 1.4)
32
+ rails-dom-testing (~> 2.0)
33
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
34
+ activejob (6.1.1)
35
+ activesupport (= 6.1.1)
36
+ globalid (>= 0.3.6)
37
+ activesupport (6.1.1)
38
+ concurrent-ruby (~> 1.0, >= 1.0.2)
39
+ i18n (>= 1.6, < 2)
40
+ minitest (>= 5.1)
41
+ tzinfo (~> 2.0)
42
+ zeitwerk (~> 2.3)
41
43
  addressable (2.7.0)
42
44
  public_suffix (>= 2.0.2, < 5.0)
45
+ ansi (1.5.0)
43
46
  builder (3.2.4)
44
47
  coderay (1.1.2)
45
- concurrent-ruby (1.1.6)
46
- contextual_logger (0.6.1)
48
+ concurrent-ruby (1.1.8)
49
+ contextual_logger (0.11.0)
47
50
  activesupport
48
51
  json
49
52
  cookiejar (0.3.3)
50
53
  crack (0.4.3)
51
54
  safe_yaml (~> 1.0.0)
52
55
  crass (1.0.6)
53
- em-http-request (1.1.5)
56
+ em-http-request (1.1.7)
54
57
  addressable (>= 2.3.4)
55
58
  cookiejar (!= 0.3.1)
56
59
  em-socksify (>= 0.3)
@@ -60,60 +63,65 @@ GEM
60
63
  eventmachine (>= 1.0.0.beta.4)
61
64
  em-synchrony (1.0.6)
62
65
  eventmachine (>= 1.0.0.beta.1)
63
- erubis (2.7.0)
66
+ erubi (1.10.0)
64
67
  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
68
+ exception_handling (2.8.1)
69
+ actionmailer (>= 4.2, < 7.0)
70
+ actionpack (>= 4.2, < 7.0)
71
+ activesupport (>= 4.2, < 7.0)
72
+ contextual_logger (~> 0.7)
70
73
  eventmachine (~> 1.0)
71
74
  invoca-utils (~> 0.3)
72
75
  globalid (0.4.2)
73
76
  activesupport (>= 4.2.0)
74
77
  hashdiff (1.0.1)
75
78
  http_parser.rb (0.6.0)
76
- i18n (0.9.5)
79
+ i18n (1.8.8)
77
80
  concurrent-ruby (~> 1.0)
78
- invoca-utils (0.3.0)
79
- json (2.3.0)
80
- loofah (2.5.0)
81
+ invoca-utils (0.4.1)
82
+ json (2.5.1)
83
+ loofah (2.9.0)
81
84
  crass (~> 1.0.2)
82
85
  nokogiri (>= 1.5.9)
83
86
  mail (2.7.1)
84
87
  mini_mime (>= 0.1.1)
85
88
  method_source (1.0.0)
86
89
  mini_mime (1.0.2)
87
- mini_portile2 (2.4.0)
90
+ mini_portile2 (2.5.0)
88
91
  minitest (5.14.0)
89
- nokogiri (1.10.9)
90
- mini_portile2 (~> 2.4.0)
92
+ minitest-reporters (1.4.2)
93
+ ansi
94
+ builder
95
+ minitest (>= 5.0)
96
+ ruby-progressbar
97
+ nokogiri (1.11.1)
98
+ mini_portile2 (~> 2.5.0)
99
+ racc (~> 1.4)
91
100
  pry (0.13.1)
92
101
  coderay (~> 1.1)
93
102
  method_source (~> 1.0)
94
103
  public_suffix (4.0.4)
95
- rack (1.6.13)
96
- rack-test (0.6.3)
97
- rack (>= 1.0)
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
+ racc (1.5.2)
105
+ rack (2.2.3)
106
+ rack-test (1.1.0)
107
+ rack (>= 1.0, < 3)
108
+ rails-dom-testing (2.0.3)
109
+ activesupport (>= 4.2.0)
110
+ nokogiri (>= 1.6)
104
111
  rails-html-sanitizer (1.3.0)
105
112
  loofah (~> 2.3)
106
113
  rake (13.0.1)
107
114
  rr (1.2.1)
115
+ ruby-progressbar (1.10.1)
108
116
  safe_yaml (1.0.5)
109
117
  thor (1.0.1)
110
- thread_safe (0.3.6)
111
- tzinfo (1.2.7)
112
- thread_safe (~> 0.1)
118
+ tzinfo (2.0.4)
119
+ concurrent-ruby (~> 1.0)
113
120
  webmock (1.24.6)
114
121
  addressable (>= 2.3.6)
115
122
  crack (>= 0.3.2)
116
123
  hashdiff
124
+ zeitwerk (2.4.2)
117
125
 
118
126
  PLATFORMS
119
127
  ruby
@@ -121,6 +129,7 @@ PLATFORMS
121
129
  DEPENDENCIES
122
130
  exceptional_synchrony!
123
131
  minitest
132
+ minitest-reporters
124
133
  pry
125
134
  rake
126
135
  rr (~> 1.2)
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
 
@@ -5,6 +5,10 @@ require 'em-http'
5
5
  require 'em-synchrony/em-http'
6
6
 
7
7
  module ExceptionalSynchrony
8
+ # It is important for this exception to be inherited from Exception so that
9
+ # when thrown it does not get caught by the EventMachine.error_handler.
10
+ class FatalRunError < Exception; end
11
+
8
12
  class EventMachineProxy
9
13
 
10
14
  attr_reader :connection
@@ -60,30 +64,41 @@ module ExceptionalSynchrony
60
64
  @proxy_class.next_tick { } #Fake out EventMachine's epoll mechanism so we don't block until timers fire
61
65
  end
62
66
 
67
+ def defers_finished?
68
+ @proxy_class.defers_finished?
69
+ end
70
+
63
71
  def connect(server, port = nil, handler = nil, *args, &block)
64
72
  @proxy_class.connect(server, port, handler, *args, &block)
65
73
  end
66
74
 
67
- def run(&block)
68
- ensure_completely_safe("run") do
69
- if @proxy_class.respond_to?(:synchrony)
70
- @proxy_class.synchrony(&block)
71
- else
72
- @proxy_class.run(&block)
73
- end
75
+ # The on_error option has these possible values:
76
+ # :log - log any rescued StandardError exceptions and continue
77
+ # :raise - raise FatalRunError for any rescued StandardError exceptions
78
+ def run(on_error: :log, &block)
79
+ configure_faraday
80
+ case on_error
81
+ when :log then run_with_error_logging(&block)
82
+ when :raise then run_with_error_raising(&block)
83
+ else raise ArgumentError, "Invalid on_error: #{on_error.inspect}, must be :log or :raise"
74
84
  end
75
85
  end
76
86
 
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
+ # This method will execute the block on the background thread pool
88
+ # By default, it will block the caller until the background thread has finished, so that the result can be returned
89
+ # :wait_for_result - setting this to false will prevent the caller from being blocked by this deferred work
90
+ def defer(context, wait_for_result: true, &block)
91
+ if wait_for_result
92
+ deferrable = EventMachine::DefaultDeferrable.new
93
+ callback = -> (result) { deferrable.succeed(result) }
94
+
95
+ EventMachine.defer(nil, callback) { CallbackExceptions.return_exception(&block) }
96
+ EventMachine::Synchrony.sync(deferrable)
97
+ CallbackExceptions.map_deferred_result(deferrable)
98
+ else
99
+ EventMachine.defer { ExceptionHandling.ensure_completely_safe("defer", &block) }
100
+ nil
101
+ end
87
102
  end
88
103
 
89
104
  def reactor_running?
@@ -108,6 +123,44 @@ module ExceptionalSynchrony
108
123
  yield
109
124
  end
110
125
  end
126
+
127
+ def rescue_exceptions_and_ensure_exit(context)
128
+ yield
129
+ rescue StandardError => ex
130
+ # Raise a non-StandardError so that not caught by EM.error_handler.
131
+ # Expecting rescued exception to be stored in this new exception's cause.
132
+ raise FatalRunError, "Fatal EventMachine #{context} error\n#{ex.class.name}: #{ex.message}"
133
+ end
134
+
135
+ private
136
+
137
+ def configure_faraday
138
+ if defined?(Faraday)
139
+ Faraday.default_adapter = :em_synchrony
140
+ end
141
+ end
142
+
143
+ def run_with_error_logging(&block)
144
+ ensure_completely_safe("run_with_error_logging") do
145
+ if @proxy_class.respond_to?(:synchrony)
146
+ @proxy_class.synchrony(&block)
147
+ else
148
+ @proxy_class.run(&block)
149
+ end
150
+ end
151
+ end
152
+
153
+ def run_with_error_raising(&block)
154
+ run_block = -> { rescue_exceptions_and_ensure_exit("run_with_error_raising", &block) }
155
+
156
+ rescue_exceptions_and_ensure_exit("run_with_error_raising") do
157
+ if @proxy_class.respond_to?(:synchrony)
158
+ @proxy_class.synchrony(&run_block)
159
+ else
160
+ @proxy_class.run(&run_block)
161
+ end
162
+ end
163
+ end
111
164
  end
112
165
 
113
166
  EMP = EventMachineProxy.new(EventMachine, EventMachine::HttpRequest)
@@ -1,3 +1,3 @@
1
1
  module ExceptionalSynchrony
2
- VERSION = '1.1.1'
2
+ VERSION = '1.4.0.pre.1'
3
3
  end
data/test/test_helper.rb CHANGED
@@ -7,6 +7,11 @@ require_relative '../lib/exceptional_synchrony.rb'
7
7
 
8
8
  require 'minitest/autorun' or raise "Already loaded minitest?"
9
9
  require 'minitest/pride'
10
+ require 'minitest/reporters'
11
+ Minitest::Reporters.use! [
12
+ Minitest::Reporters::DefaultReporter.new,
13
+ Minitest::Reporters::JUnitReporter.new
14
+ ]
10
15
  require 'webmock'
11
16
  require 'webmock/minitest'
12
17
  require 'rr'
@@ -3,10 +3,39 @@ require_relative '../test_helper'
3
3
  describe ExceptionalSynchrony::EventMachineProxy do
4
4
  include TestHelper
5
5
 
6
+ class RunProxyMock
7
+ class << self
8
+ def run(&block)
9
+ block.call
10
+ :run
11
+ end
12
+
13
+ def error_handler
14
+ end
15
+ end
16
+ end
17
+
18
+ class SynchronyProxyMock < RunProxyMock
19
+ class << self
20
+ def synchrony(&block)
21
+ block.call
22
+ :synchrony
23
+ end
24
+ end
25
+ end
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
+
6
35
  before do
7
36
  @em = ExceptionalSynchrony::EventMachineProxy.new(EventMachine, nil)
8
37
  @yielded_value = nil
9
- @block = lambda { |value| @yielded_value = value }
38
+ @block = -> (value) { @yielded_value = value }
10
39
  end
11
40
 
12
41
  it "should proxy add_timer" do
@@ -57,18 +86,41 @@ describe ExceptionalSynchrony::EventMachineProxy do
57
86
  end
58
87
 
59
88
  describe "#defer" do
60
- it "should output its block's output when it doesn't raise an error" do
61
- ExceptionHandling.logger = Logger.new(STDERR)
89
+ before do
90
+ logger = Logger.new(STDERR)
91
+ logger.extend ContextualLogger::LoggerMixin
92
+ ExceptionHandling.logger = logger
93
+ end
62
94
 
95
+ it "should output its block's output when it doesn't raise an error, by default" do
63
96
  @em.run do
64
97
  assert_equal 12, @em.defer("#defer success") { 12 }
65
98
  @em.stop
66
99
  end
67
100
  end
68
101
 
69
- it "should raise an error when its block raises an error" do
70
- 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", {})
71
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
72
124
  @em.run do
73
125
  ex = assert_raises(ArgumentError) do
74
126
  @em.defer("#defer raising an error") { raise ArgumentError, "!!!" }
@@ -106,27 +158,71 @@ describe ExceptionalSynchrony::EventMachineProxy do
106
158
  end
107
159
  end
108
160
 
109
- [false, true].each do |synchrony|
110
- describe "synchrony = #{synchrony}" do
111
- it "should dispatch to the proxy's synchrony method instead of run iff synchrony" do
112
- proxy_mock = Struct.new(:proxy, :class_connection) do
113
- if synchrony
114
- def self.synchrony(&block)
115
- block.(:synchrony)
116
- end
161
+ describe "run with faraday" do
162
+ it "should conigure Faraday default_adapter to :em_synchrony if Faraday is defined" do
163
+ class Faraday
164
+ class << self
165
+ attr_reader :default_adapter
166
+
167
+ def default_adapter=(adapter)
168
+ @default_adapter = adapter
117
169
  end
170
+ end
171
+
172
+ self.default_adapter = :net_http
173
+ end
174
+
175
+ mock(@em).run_with_error_logging
176
+ assert_equal :net_http, Faraday.default_adapter
177
+ @em.run
178
+ assert_equal :em_synchrony, Faraday.default_adapter
179
+ end
180
+ end
181
+
182
+ { synchrony: SynchronyProxyMock, run: RunProxyMock }.each do |method, proxy_mock|
183
+ describe "run" do
184
+ before do
185
+ @proxy = ExceptionalSynchrony::EventMachineProxy.new(proxy_mock, nil)
186
+ end
118
187
 
119
- def self.run(&block)
120
- block.(:run)
188
+ it "should raise ArgumentError if on_error has invalid value" do
189
+ assert_raises(ArgumentError, "Invalid on_error: :ignore, must be :log or :raise") do
190
+ @proxy.run(on_error: :ignore)
191
+ end
192
+ end
193
+
194
+ describe "without error" do
195
+ [:log, :raise].each do |on_error|
196
+ describe "when using #{method} and on_error = #{on_error}" do
197
+ it "should dispatch to the proxy's synchrony method instead of run iff synchrony" do
198
+ dispatched = false
199
+ assert_equal method, (@proxy.run(on_error: on_error) { dispatched = true })
200
+ assert_equal true, dispatched
201
+ end
121
202
  end
122
203
  end
204
+ end
205
+
206
+ describe "with error" do
207
+ before do
208
+ set_test_const('ExceptionalSynchrony::EventMachineProxy::WRAP_WITH_ENSURE_COMPLETELY_SAFE', true)
209
+ end
123
210
 
124
- mock(proxy_mock).error_handler
211
+ describe "when using #{method} and on_error = :log" do
212
+ it "should rescue any exceptions and log them" do
213
+ mock(ExceptionHandling).log_error(EXCEPTION, "run_with_error_logging", {})
125
214
 
126
- proxy = ExceptionalSynchrony::EventMachineProxy.new(proxy_mock, nil)
215
+ @proxy.run(on_error: :log) { raise EXCEPTION }
216
+ end
217
+ end
127
218
 
128
- proxy.run(&@block)
129
- expect(@yielded_value).must_equal(synchrony ? :synchrony : :run)
219
+ describe "when using #{method} and on_error = :raise" do
220
+ it "should rescue any exceptions and raise FatalRunError" do
221
+ assert_raises(ExceptionalSynchrony::FatalRunError, "Fatal EventMachine run error") do
222
+ @proxy.run(on_error: :raise) { raise EXCEPTION }
223
+ end
224
+ end
225
+ end
130
226
  end
131
227
  end
132
228
  end
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.1.1
4
+ version: 1.4.0.pre.1
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
@@ -88,6 +88,8 @@ extra_rdoc_files: []
88
88
  files:
89
89
  - ".dependabot/config.yml"
90
90
  - ".gitignore"
91
+ - ".jenkins/Jenkinsfile"
92
+ - ".jenkins/ruby_build_pod.yml"
91
93
  - ".ruby-gemset"
92
94
  - ".ruby-version"
93
95
  - CHANGELOG.md
@@ -102,7 +104,6 @@ files:
102
104
  - lib/exceptional_synchrony/limited_work_queue.rb
103
105
  - lib/exceptional_synchrony/parallel_sync.rb
104
106
  - lib/exceptional_synchrony/version.rb
105
- - semaphore_ci/setup.sh
106
107
  - test/test_helper.rb
107
108
  - test/unit/callback_exceptions_test.rb
108
109
  - test/unit/event_machine_proxy_test.rb
@@ -114,7 +115,7 @@ licenses:
114
115
  metadata:
115
116
  source_code_uri: https://github.com/Invoca/exceptional_synchrony
116
117
  allowed_push_host: https://rubygems.org
117
- post_install_message:
118
+ post_install_message:
118
119
  rdoc_options: []
119
120
  require_paths:
120
121
  - lib
@@ -125,12 +126,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
126
  version: '0'
126
127
  required_rubygems_version: !ruby/object:Gem::Requirement
127
128
  requirements:
128
- - - ">="
129
+ - - ">"
129
130
  - !ruby/object:Gem::Version
130
- version: '0'
131
+ version: 1.3.1
131
132
  requirements: []
132
133
  rubygems_version: 3.0.3
133
- signing_key:
134
+ signing_key:
134
135
  specification_version: 4
135
136
  summary: Extensions to EventMachine/Synchrony to work well with exceptions
136
137
  test_files: []
@@ -1,3 +0,0 @@
1
- #!/bin/sh -x
2
-
3
- bundle install --path vendor/bundle