@@ 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