Merge branch 'rack-trampoline'

Stephen Paul Weber created

* rack-trampoline:
  Wrap rack requests in an EMPromise fiber trampoline, and not just a Fiber

Change summary

lib/rack_fiber.rb | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)

Detailed changes

lib/rack_fiber.rb 🔗

@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 
-require "fiber"
+require "em_promise"
 
 module Rack
 	class Fiber
@@ -10,20 +10,21 @@ module Rack
 
 		def call(env)
 			async_callback = env.delete("async.callback")
-			EM.next_tick { run_fiber(env, async_callback) }
+			run_fiber(env, async_callback)
 			throw :async
 		end
 
 	protected
 
 		def run_fiber(env, async_callback)
-			::Fiber.new {
-				begin
-					async_callback.call(@app.call(env))
-				rescue ::Exception # rubocop:disable Lint/RescueException
-					async_callback.call([500, {}, [$!.to_s]])
-				end
-			}.resume
+			# Use EMPromise to get a Fiber trampoline that can be shared by
+			# other EMPromise down the stack. Also works as a normal Fiber if
+			# no one uses EMPromise.
+			EMPromise.resolve(nil).then {
+				async_callback.call(@app.call(env))
+			}.catch { |e|
+				async_callback.call([500, {}, [e.to_s]])
+			}
 		end
 	end
 end