Module: Rack::Handler::Homura
- Defined in:
- lib/homura/runtime.rb
Constant Summary collapse
- EMPTY_STRING_IO =
StringIO.new("").freeze
Class Method Summary collapse
- .app ⇒ Object
- .app=(app) ⇒ Object
-
.call(js_req, js_env, js_ctx, body_text = "") ⇒ Object
Entry point invoked from the Module Worker (src/worker.mjs) for every fetch event.
-
.ensure_dispatcher_installed! ⇒ Object
Eagerly install the JS-side dispatcher so a fetch arriving before ‘run` was called (e.g. classic-style apps that omit the trailing `run Sinatra::Application`) still gets routed into our `call` method, which can then discover the user’s Sinatra app lazily via ‘Sinatra::Homura.ensure_rack_app!`.
- .run(app, **_options) ⇒ Object
Class Method Details
.app ⇒ Object
156 157 158 |
# File 'lib/homura/runtime.rb', line 156 def self.app @app end |
.app=(app) ⇒ Object
160 161 162 |
# File 'lib/homura/runtime.rb', line 160 def self.app=(app) @app = app end |
.call(js_req, js_env, js_ctx, body_text = "") ⇒ Object
Entry point invoked from the Module Worker (src/worker.mjs) for every fetch event. ‘js_req` is a Cloudflare Workers Request, `js_env` is the bindings object (D1, KV, R2, secrets…), `js_ctx` is the ExecutionContext, `body_text` is the pre-resolved request body (the worker.mjs front awaits req.text() before handing control to Ruby because Opal runs synchronously).
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/homura/runtime.rb', line 194 def self.call(js_req, js_env, js_ctx, body_text = "") if @app.nil? if defined?(::Sinatra::Homura) && ::Sinatra::Homura.respond_to?(:ensure_rack_app!) ::Sinatra::Homura.ensure_rack_app! end if @app.nil? raise( "`run app` was never called from user code, and no Sinatra app was discoverable (define `class App < Sinatra::Base` or use top-level classic Sinatra routes)" ) end end env = build_rack_env(js_req, js_env, js_ctx, body_text) result = @app.call(env) if defined?(::Cloudflare) && ::Cloudflare.js_promise?(result) result = result.__await__ end status, headers, body = result build_js_response(status, headers, body) ensure body.close if body && body.respond_to?(:close) end |
.ensure_dispatcher_installed! ⇒ Object
Eagerly install the JS-side dispatcher so a fetch arriving before ‘run` was called (e.g. classic-style apps that omit the trailing `run Sinatra::Application`) still gets routed into our `call` method, which can then discover the user’s Sinatra app lazily via ‘Sinatra::Homura.ensure_rack_app!`. This is what makes the canonical sinatrarb.com snippet work verbatim on Workers — `at_exit` is unreliable here because the isolate never actually exits between fetches.
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/homura/runtime.rb', line 172 def self.ensure_dispatcher_installed! return true if @dispatcher_installed handler = self ` globalThis.__HOMURA_RACK_DISPATCH__ = async function(req, env, ctx, body_text) { return await #{handler}.$call(req, env, ctx, body_text == null ? "" : body_text); }; (function () { var g = globalThis; g.__OPAL_WORKERS__ = g.__OPAL_WORKERS__ || {}; g.__OPAL_WORKERS__.rack = g.__HOMURA_RACK_DISPATCH__; })(); ` @dispatcher_installed = true end |
.run(app, **_options) ⇒ Object
150 151 152 153 154 |
# File 'lib/homura/runtime.rb', line 150 def self.run(app, **) @app = app ensure_dispatcher_installed! app end |