# frozen_string_literal: true require "em_promise" module Rack class Fiber def initialize(app) @app = app end def call(env) async_callback = env.delete("async.callback") run_fiber(env, async_callback) throw :async end protected def run_fiber(env, async_callback) # 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