From 097cc678c775636a001f17427775e4125186c7a6 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Wed, 20 Oct 2021 10:29:48 -0500 Subject: [PATCH] Wrap rack requests in an EMPromise fiber trampoline, and not just a Fiber --- lib/rack_fiber.rb | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/rack_fiber.rb b/lib/rack_fiber.rb index c30e06e..eda0596 100644 --- a/lib/rack_fiber.rb +++ b/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 -- 2.34.2