-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ML] Explain log rate spikes: Move API stream demos to Kibana example…
…s. (#132590) This creates a response_stream plugin in the Kibana /examples section. The plugin demonstrates API endpoints that can stream data chunks with a single request with gzip/compression support. gzip-streams get decompressed natively by browsers. The plugin demonstrates two use cases to get started: Streaming a raw string as well as a more complex example that streams Redux-like actions to the client which update React state via useReducer().
- Loading branch information
Showing
69 changed files
with
1,706 additions
and
738 deletions.
There are no files selected for viewing
Validating CODEOWNERS rules …
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
## response stream | ||
|
||
This plugin demonstrates how to stream chunks of data to the client with just a single request. | ||
|
||
To run Kibana with the described examples, use `yarn start --run-examples`. | ||
|
||
The `response_stream` plugin demonstrates API endpoints that can stream data chunks with a single request with gzip/compression support. gzip-streams get decompressed natively by browsers. The plugin demonstrates two use cases to get started: Streaming a raw string as well as a more complex example that streams Redux-like actions to the client which update React state via `useReducer()`. | ||
|
||
Code in `@kbn/aiops-utils` contains helpers to set up a stream on the server side (`streamFactory()`) and consume it on the client side via a custom hook (`useFetchStream()`). The utilities make use of TS generics in a way that allows to have type safety for both request related options as well as the returned data. | ||
|
||
No additional third party libraries are used in the helpers to make it work. On the server, they integrate with `Hapi` and use node's own `gzip`. On the client, the custom hook abstracts away the necessary logic to consume the stream, internally it makes use of a generator function and `useReducer()` to update React state. | ||
|
||
On the server, the simpler stream to send a string is set up like this: | ||
|
||
```ts | ||
const { end, push, responseWithHeaders } = streamFactory(request.headers); | ||
``` | ||
|
||
The request's headers get passed on to automatically identify if compression is supported by the client. | ||
|
||
On the client, the custom hook is used like this: | ||
|
||
```ts | ||
const { error, start, cancel, data, isRunning } = useFetchStream< | ||
ApiSimpleStringStream, typeof basePath | ||
>(`${basePath}/internal/response_stream/simple_string_stream`); | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
The `./api` folder contains shared code used to support working with the same type specifications on server and client. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import type { | ||
UseFetchStreamCustomReducerParams, | ||
UseFetchStreamParamsDefault, | ||
} from '@kbn/aiops-utils'; | ||
|
||
import { | ||
reducerStreamReducer, | ||
ReducerStreamRequestBodySchema, | ||
ReducerStreamApiAction, | ||
} from './reducer_stream'; | ||
import { SimpleStringStreamRequestBodySchema } from './simple_string_stream'; | ||
|
||
export const API_ENDPOINT = { | ||
REDUCER_STREAM: '/internal/response_stream/reducer_stream', | ||
SIMPLE_STRING_STREAM: '/internal/response_stream/simple_string_stream', | ||
} as const; | ||
|
||
export interface ApiReducerStream extends UseFetchStreamCustomReducerParams { | ||
endpoint: typeof API_ENDPOINT.REDUCER_STREAM; | ||
reducer: typeof reducerStreamReducer; | ||
body: ReducerStreamRequestBodySchema; | ||
actions: ReducerStreamApiAction; | ||
} | ||
|
||
export interface ApiSimpleStringStream extends UseFetchStreamParamsDefault { | ||
endpoint: typeof API_ENDPOINT.SIMPLE_STRING_STREAM; | ||
body: SimpleStringStreamRequestBodySchema; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
examples/response_stream/common/api/reducer_stream/request_body_schema.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import { schema, TypeOf } from '@kbn/config-schema'; | ||
|
||
export const reducerStreamRequestBodySchema = schema.object({ | ||
/** Boolean flag to enable/disabling simulation of response errors. */ | ||
simulateErrors: schema.maybe(schema.boolean()), | ||
/** Maximum timeout between streaming messages. */ | ||
timeout: schema.maybe(schema.number()), | ||
}); | ||
export type ReducerStreamRequestBodySchema = TypeOf<typeof reducerStreamRequestBodySchema>; |
10 changes: 10 additions & 0 deletions
10
examples/response_stream/common/api/simple_string_stream/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
export { simpleStringStreamRequestBodySchema } from './request_body_schema'; | ||
export type { SimpleStringStreamRequestBodySchema } from './request_body_schema'; |
17 changes: 17 additions & 0 deletions
17
examples/response_stream/common/api/simple_string_stream/request_body_schema.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import { schema, TypeOf } from '@kbn/config-schema'; | ||
|
||
export const simpleStringStreamRequestBodySchema = schema.object({ | ||
/** Maximum timeout between streaming messages. */ | ||
timeout: schema.number(), | ||
}); | ||
export type SimpleStringStreamRequestBodySchema = TypeOf< | ||
typeof simpleStringStreamRequestBodySchema | ||
>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"id": "responseStream", | ||
"kibanaVersion": "kibana", | ||
"version": "0.0.1", | ||
"server": true, | ||
"ui": true, | ||
"owner": { | ||
"name": "ML UI", | ||
"githubTeam": "ml-ui" | ||
}, | ||
"requiredPlugins": ["developerExamples"], | ||
"optionalPlugins": [], | ||
"requiredBundles": ["kibanaReact"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import * as React from 'react'; | ||
|
||
import { | ||
EuiPageBody, | ||
EuiPageContent, | ||
EuiPageContentBody, | ||
EuiPageHeader, | ||
EuiPageHeaderSection, | ||
EuiTitle, | ||
} from '@elastic/eui'; | ||
|
||
export interface PageProps { | ||
title?: React.ReactNode; | ||
} | ||
|
||
export const Page: React.FC<PageProps> = ({ title = 'Untitled', children }) => { | ||
return ( | ||
<EuiPageBody> | ||
<EuiPageHeader> | ||
<EuiPageHeaderSection> | ||
<EuiTitle size="l"> | ||
<h1>{title}</h1> | ||
</EuiTitle> | ||
</EuiPageHeaderSection> | ||
</EuiPageHeader> | ||
<EuiPageContent> | ||
<EuiPageContentBody style={{ maxWidth: 800, margin: '0 auto' }}> | ||
{children} | ||
</EuiPageContentBody> | ||
</EuiPageContent> | ||
</EuiPageBody> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import React from 'react'; | ||
import { BrowserRouter as Router, Route, Redirect, Switch } from 'react-router-dom'; | ||
import { EuiPage } from '@elastic/eui'; | ||
import { useDeps } from '../../hooks/use_deps'; | ||
import { Sidebar } from './sidebar'; | ||
import { routes } from '../../routes'; | ||
|
||
export const App: React.FC = () => { | ||
const { appBasePath } = useDeps(); | ||
|
||
const routeElements: React.ReactElement[] = []; | ||
for (const { items } of routes) { | ||
for (const { id, component } of items) { | ||
routeElements.push(<Route key={id} path={`/${id}`} render={(props) => component} />); | ||
} | ||
} | ||
|
||
return ( | ||
<Router basename={appBasePath}> | ||
<EuiPage> | ||
<Sidebar /> | ||
<Switch> | ||
{routeElements} | ||
<Redirect to="/simple-string-stream" /> | ||
</Switch> | ||
</EuiPage> | ||
</Router> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.