Add EventStreamHttpResponse for Server-Sent Events.

Review Request #13280 — Created Sept. 20, 2023 and submitted

Information

Djblets
release-4.x

Reviewers

This introduces djblets.http.responses.EventStreamHttpResponse, which
can stream events and data to a client by way of the Server-Sent Events
(SSE) standard.

This works by taking a generator or callable that yields dictionaries of
message data following the spec, allowing for app-specified IDs,
text-based payload data, event names, and retry intervals (for
disconnects) to be streamed to the client.

The response class takes charge of serializing this information for the
client, and can also support resuming of streamed events by intercepting
the SSE Last-Event-ID header and passing it to an event stream
callable.

It's important for consumers of this class to be mindful of how it's
used. Browsers have a limit of 6 concurrent HTTP/1.1 requests to the
same domain across all tabs, and a long-running SSE stream will take one
of those slots, potentially starving out other requests. This is far
less of a problem with HTTP/2.

Unit tests pass.

Tested with a makeshift EventSource implementation in JavaScript,
testing that events and all fields were successfully coming in and
processing as per spec.

Tested with curl and with GZip middleware turned on and off.

Summary ID
Add EventStreamHttpResponse for Server-Sent Events.
This introduces `djblets.http.responses.EventStreamHttpResponse`, which can stream events and data to a client by way of the Server-Sent Events (SSE) standard. This works by taking a generator or callable that yields dictionaries of message data following the spec, allowing for app-specified IDs, text-based payload data, event names, and retry intervals (for disconnects) to be streamed to the client. The response class takes charge of serializing this information for the client, and can also support resuming of streamed events by intercepting the SSE `Last-Event-ID` header and passing it to an event stream callable. It's important for consumers of this class to be mindful of how it's used. Browsers have a limit of 6 concurrent HTTP/1.1 requests to the same domain across all tabs, and a long-running SSE stream will take one of those slots, potentially starving out other requests. This is far less of a problem with HTTP/2.
ff191009cb1bb5c8814bfeadb4792b00bfc4781c
Description From Last Updated

'typing.NoReturn' imported but unused Column: 1 Error code: F401

reviewbotreviewbot

'djblets.http.responses.EventStream' imported but unused Column: 1 Error code: F401

reviewbotreviewbot

I think this should just say "A message in an event stream". "generated" doesn't add anything.

daviddavid
Checks run (1 failed, 1 succeeded)
flake8 failed.
JSHint passed.

flake8

chipx86
david
  1. 
      
  2. djblets/http/responses.py (Diff revision 2)
     
     
    Show all issues

    I think this should just say "A message in an event stream". "generated" doesn't add anything.

  3. 
      
maubin
  1. Ship It!
  2. 
      
chipx86
Review request changed
Status:
Completed
Change Summary:
Pushed to release-4.x (26ac188)