Class: Cloudflare::SSEStream
- Inherits:
-
Object
- Object
- Cloudflare::SSEStream
- Defined in:
- lib/cloudflare_workers/stream.rb
Overview
Stream returned from a Sinatra route. ‘build_js_response` checks `#sse_stream?` and hands the JS readable stream straight to Workers’ ‘new Response(readable, { headers })`.
Constant Summary collapse
- DEFAULT_HEADERS =
{ 'content-type' => 'text/event-stream; charset=utf-8', 'cache-control' => 'no-cache, no-transform', 'x-accel-buffering' => 'no', 'connection' => 'keep-alive' }.freeze
Instance Method Summary collapse
- #close ⇒ Object
-
#each ⇒ Object
Rack body contract.
-
#initialize(headers: nil, ctx: nil, &block) ⇒ SSEStream
constructor
A new instance of SSEStream.
-
#js_stream ⇒ Object
Build the JS ReadableStream lazily — build_js_response calls ‘.js_stream`.
-
#response_headers ⇒ Object
Merged header set to emit on the Response.
-
#sse_stream? ⇒ Boolean
Duck-typed marker consumed by Rack::Handler::CloudflareWorkers.
Constructor Details
#initialize(headers: nil, ctx: nil, &block) ⇒ SSEStream
Returns a new instance of SSEStream.
44 45 46 47 48 49 |
# File 'lib/cloudflare_workers/stream.rb', line 44 def initialize(headers: nil, ctx: nil, &block) @block = block @ctx = ctx @extra_headers = headers || {} @js_stream = nil end |
Instance Method Details
#close ⇒ Object
90 |
# File 'lib/cloudflare_workers/stream.rb', line 90 def close; end |
#each ⇒ Object
Rack body contract. Iterating is a no-op — the actual bytes flow through the JS pipe. Sinatra’s content-length calculator therefore sees no body and leaves the header out, which is exactly right for a chunked streaming response.
89 |
# File 'lib/cloudflare_workers/stream.rb', line 89 def each; end |
#js_stream ⇒ Object
Build the JS ReadableStream lazily — build_js_response calls ‘.js_stream`. After this point the async task is running; we can only do it once per stream.
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/cloudflare_workers/stream.rb', line 64 def js_stream return @js_stream if @js_stream blk = @block ctx = @ctx raise ArgumentError, 'SSEStream needs a block' if blk.nil? ts = `new TransformStream()` writer = `#{ts}.writable.getWriter()` out = SSEOut.new(writer) # Kick off the user block in an async task. run_stream compiles # to a JS async function (this file is `# await: true`), so # calling it returns a Promise; we bind it to ctx.waitUntil so # the Workers runtime doesn't tear the isolate down before the # stream finishes. promise = run_stream(out, blk) `#{ctx}.waitUntil(#{promise})` if ctx @js_stream = `#{ts}.readable` end |
#response_headers ⇒ Object
Merged header set to emit on the Response.
57 58 59 |
# File 'lib/cloudflare_workers/stream.rb', line 57 def response_headers DEFAULT_HEADERS.merge(@extra_headers) end |
#sse_stream? ⇒ Boolean
Duck-typed marker consumed by Rack::Handler::CloudflareWorkers.
52 53 54 |
# File 'lib/cloudflare_workers/stream.rb', line 52 def sse_stream? true end |