~singpolyma/sgx-jmp

097cc678c775636a001f17427775e4125186c7a6 — Stephen Paul Weber 2 months ago 2f7a1b6
Wrap rack requests in an EMPromise fiber trampoline, and not just a Fiber
1 files changed, 10 insertions(+), 9 deletions(-)

M lib/rack_fiber.rb
M lib/rack_fiber.rb => lib/rack_fiber.rb +10 -9
@@ 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