exceptional_synchrony 1.1.1 → 1.4.0.pre.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 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