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