elastic / kibana

Your window into the Elastic Stack
https://www.elastic.co/products/kibana
Other
19.64k stars 8.23k forks source link

Add SSE support to Core HTTP APIs #198913

Open pgayvallet opened 1 week ago

pgayvallet commented 1 week ago

Right now, if SSE between the Kibana server and browser can be technically achieved, implementing it is very tedious and "manual".

On the server-side, it was basically only made possible by the fact that we can send a stream as response's body. The conversion to any kind of "observable" or "event emitter" to an SSE-compatible ("event source") stream must be implemented by the endpoint owner.

E.g.

https://github.com/elastic/kibana/blob/253cf6e12d68b8a1836ee4063f69466cd53759b3/x-pack/plugins/inference/server/routes/chat_complete.ts#L141-L146

Same goes for the browser side: the SSE stream can be handled due to the asResponse and rawResponse parameter of our fetch service, but there's no tool out of the box to convert the stream back to some kind of typed observable

E.g.

https://github.com/elastic/kibana/blob/1bd42ad6ea05872d3f30eb6d379c39ed37879dfc/x-pack/plugins/inference/public/chat_complete.ts#L43-L49

Ideally, Core HTTP APIs should have better / native support for SSE endpoints, which would make DX around SSE better, in addition to allow the encode/decode logic to be factorized in a single, platform, place.

elasticmachine commented 1 week ago

Pinging @elastic/kibana-core (Team:Core)

jloleysens commented 1 week ago

As we have also discussed offline, one risk here is when not using HTTP/2 we have a limited number of connections to also manage which a Core owned implementation could help manage:

When not used over HTTP/2, SSE suffers from a limitation to the maximum number of open connections, which can be especially painful when opening multiple tabs, as the limit is per browser and is set to a very low number (6). The issue has been marked as "Won't fix" in Chrome and Firefox. This limit is per browser + domain, which means that you can open 6 SSE connections across all of the tabs to www.example1.com and another 6 SSE connections to www.example2.com (per StackOverflow). When using HTTP/2, the maximum number of simultaneous HTTP streams is negotiated between the server and the client (defaults to 100).

--- Excerpt from MDN

rudolf commented 1 week ago

I'm not 100% sure if we've stayed consistent in this. But we have traditionally tried to keep the API surface of Core as small as possible by avoiding leaking large API surfaces like an Observable (not holding my breath that it would ever get added to ECMAScript). Another way to achieve this could be to expose a stream that can then be very easily turned into an observable with Observable.from.

afharo commented 1 week ago

Looking at the code examples, it feels like a helper package to convert the response to SSE would suffice. WDYT?