Skip to content

Commit

Permalink
Migrate most plugins to synchronous lifecycle (#89562)
Browse files Browse the repository at this point in the history
* first pass

* migrate more plugins

* migrate yet more plugins

* more oss plugins

* fix test file

* change Plugin signature on the client-side too

* fix test types

* migrate OSS client-side plugins

* migrate OSS client-side test plugins

* migrate xpack client-side plugins

* revert fix attempt on fleet plugin

* fix presentation start signature

* fix yet another signature

* add warnings for server-side async plugins in dev mode

* remove unused import

* fix isPromise

* Add client-side deprecations

* update migration examples

* update generated doc

* fix xpack unit tests

* nit

* (will be reverted) explicitly await for license to be ready in the auth hook

* Revert "(will be reverted) explicitly await for license to be ready in the auth hook"

This reverts commit fdf73fe

* restore await on on promise contracts

* Revert "(will be reverted) explicitly await for license to be ready in the auth hook"

This reverts commit fdf73fe

* Revert "restore await on on promise contracts"

This reverts commit c5f2fe5

* add delay before starting tests in FTR

* update deprecation ts doc

* add explicit contract for monitoring setup

* migrate monitoring plugin to sync

* change plugin timeout to 10sec

* use delay instead of silence
  • Loading branch information
pgayvallet committed Feb 8, 2021
1 parent 2279c06 commit 3b3327d
Show file tree
Hide file tree
Showing 114 changed files with 1,000 additions and 550 deletions.
12 changes: 5 additions & 7 deletions docs/developer/plugin/migrating-legacy-plugins-examples.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,20 @@ export function plugin(initializerContext: PluginInitializerContext) {
*plugins/my_plugin/(public|server)/plugin.ts*
[source,typescript]
----
import type { Observable } from 'rxjs';
import { first } from 'rxjs/operators';
import { CoreSetup, Logger, Plugin, PluginInitializerContext, PluginName } from 'kibana/server';
import type { MyPluginConfig } from './config';
export class MyPlugin implements Plugin {
private readonly config$: Observable<MyPluginConfig>;
private readonly config: MyPluginConfig;
private readonly log: Logger;
constructor(private readonly initializerContext: PluginInitializerContext) {
this.log = initializerContext.logger.get();
this.config$ = initializerContext.config.create();
this.config = initializerContext.config.get<MyPluginConfig>();
}
public async setup(core: CoreSetup, deps: Record<PluginName, unknown>) {
const isEnabled = await this.config$.pipe(first()).toPromise();
public setup(core: CoreSetup, deps: Record<PluginName, unknown>) {
const { someConfigValue } = this.config;
}
}
----
Expand All @@ -96,7 +94,7 @@ Additionally, some plugins need to access the runtime env configuration.
[source,typescript]
----
export class MyPlugin implements Plugin {
public async setup(core: CoreSetup, deps: Record<PluginName, unknown>) {
public setup(core: CoreSetup, deps: Record<PluginName, unknown>) {
const { mode: { dev }, packageInfo: { version } } = this.initializerContext.env
}
----
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-public](./kibana-plugin-core-public.md) &gt; [AsyncPlugin](./kibana-plugin-core-public.asyncplugin.md)

## AsyncPlugin interface

> Warning: This API is now obsolete.
>
> Asynchronous lifecycles are deprecated, and should be migrated to sync [plugin](./kibana-plugin-core-public.plugin.md)
>
A plugin with asynchronous lifecycle methods.

<b>Signature:</b>

```typescript
export interface AsyncPlugin<TSetup = void, TStart = void, TPluginsSetup extends object = object, TPluginsStart extends object = object>
```

## Methods

| Method | Description |
| --- | --- |
| [setup(core, plugins)](./kibana-plugin-core-public.asyncplugin.setup.md) | |
| [start(core, plugins)](./kibana-plugin-core-public.asyncplugin.start.md) | |
| [stop()](./kibana-plugin-core-public.asyncplugin.stop.md) | |

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-public](./kibana-plugin-core-public.md) &gt; [AsyncPlugin](./kibana-plugin-core-public.asyncplugin.md) &gt; [setup](./kibana-plugin-core-public.asyncplugin.setup.md)

## AsyncPlugin.setup() method

<b>Signature:</b>

```typescript
setup(core: CoreSetup<TPluginsStart, TStart>, plugins: TPluginsSetup): TSetup | Promise<TSetup>;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| core | <code>CoreSetup&lt;TPluginsStart, TStart&gt;</code> | |
| plugins | <code>TPluginsSetup</code> | |

<b>Returns:</b>

`TSetup | Promise<TSetup>`

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-public](./kibana-plugin-core-public.md) &gt; [AsyncPlugin](./kibana-plugin-core-public.asyncplugin.md) &gt; [start](./kibana-plugin-core-public.asyncplugin.start.md)

## AsyncPlugin.start() method

<b>Signature:</b>

```typescript
start(core: CoreStart, plugins: TPluginsStart): TStart | Promise<TStart>;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| core | <code>CoreStart</code> | |
| plugins | <code>TPluginsStart</code> | |

<b>Returns:</b>

`TStart | Promise<TStart>`

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-public](./kibana-plugin-core-public.md) &gt; [AsyncPlugin](./kibana-plugin-core-public.asyncplugin.md) &gt; [stop](./kibana-plugin-core-public.asyncplugin.stop.md)

## AsyncPlugin.stop() method

<b>Signature:</b>

```typescript
stop?(): void;
```
<b>Returns:</b>
`void`
1 change: 1 addition & 0 deletions docs/development/core/public/kibana-plugin-core-public.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [ApplicationStart](./kibana-plugin-core-public.applicationstart.md) | |
| [AppMeta](./kibana-plugin-core-public.appmeta.md) | Input type for meta data for an application.<!-- -->Meta fields include <code>keywords</code> and <code>searchDeepLinks</code> Keywords is an array of string with which to associate the app, must include at least one unique string as an array. <code>searchDeepLinks</code> is an array of links that represent secondary in-app locations for the app. |
| [AppMountParameters](./kibana-plugin-core-public.appmountparameters.md) | |
| [AsyncPlugin](./kibana-plugin-core-public.asyncplugin.md) | A plugin with asynchronous lifecycle methods. |
| [Capabilities](./kibana-plugin-core-public.capabilities.md) | The read-only set of capabilities available for the current UI session. Capabilities are simple key-value pairs of (string, boolean), where the string denotes the capability ID, and the boolean is a flag indicating if the capability is enabled or disabled. |
| [ChromeBadge](./kibana-plugin-core-public.chromebadge.md) | |
| [ChromeBrand](./kibana-plugin-core-public.chromebrand.md) | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<b>Signature:</b>

```typescript
setup(core: CoreSetup<TPluginsStart, TStart>, plugins: TPluginsSetup): TSetup | Promise<TSetup>;
setup(core: CoreSetup<TPluginsStart, TStart>, plugins: TPluginsSetup): TSetup;
```

## Parameters
Expand All @@ -19,5 +19,5 @@ setup(core: CoreSetup<TPluginsStart, TStart>, plugins: TPluginsSetup): TSetup |

<b>Returns:</b>

`TSetup | Promise<TSetup>`
`TSetup`

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<b>Signature:</b>

```typescript
start(core: CoreStart, plugins: TPluginsStart): TStart | Promise<TStart>;
start(core: CoreStart, plugins: TPluginsStart): TStart;
```

## Parameters
Expand All @@ -19,5 +19,5 @@ start(core: CoreStart, plugins: TPluginsStart): TStart | Promise<TStart>;

<b>Returns:</b>

`TStart | Promise<TStart>`
`TStart`

Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ The `plugin` export at the root of a plugin's `public` directory should conform
<b>Signature:</b>

```typescript
export declare type PluginInitializer<TSetup, TStart, TPluginsSetup extends object = object, TPluginsStart extends object = object> = (core: PluginInitializerContext) => Plugin<TSetup, TStart, TPluginsSetup, TPluginsStart>;
export declare type PluginInitializer<TSetup, TStart, TPluginsSetup extends object = object, TPluginsStart extends object = object> = (core: PluginInitializerContext) => Plugin<TSetup, TStart, TPluginsSetup, TPluginsStart> | AsyncPlugin<TSetup, TStart, TPluginsSetup, TPluginsStart>;
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [AsyncPlugin](./kibana-plugin-core-server.asyncplugin.md)

## AsyncPlugin interface

> Warning: This API is now obsolete.
>
> Asynchronous lifecycles are deprecated, and should be migrated to sync [plugin](./kibana-plugin-core-server.plugin.md)
>
A plugin with asynchronous lifecycle methods.

<b>Signature:</b>

```typescript
export interface AsyncPlugin<TSetup = void, TStart = void, TPluginsSetup extends object = object, TPluginsStart extends object = object>
```

## Methods

| Method | Description |
| --- | --- |
| [setup(core, plugins)](./kibana-plugin-core-server.asyncplugin.setup.md) | |
| [start(core, plugins)](./kibana-plugin-core-server.asyncplugin.start.md) | |
| [stop()](./kibana-plugin-core-server.asyncplugin.stop.md) | |

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [AsyncPlugin](./kibana-plugin-core-server.asyncplugin.md) &gt; [setup](./kibana-plugin-core-server.asyncplugin.setup.md)

## AsyncPlugin.setup() method

<b>Signature:</b>

```typescript
setup(core: CoreSetup, plugins: TPluginsSetup): TSetup | Promise<TSetup>;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| core | <code>CoreSetup</code> | |
| plugins | <code>TPluginsSetup</code> | |

<b>Returns:</b>

`TSetup | Promise<TSetup>`

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [AsyncPlugin](./kibana-plugin-core-server.asyncplugin.md) &gt; [start](./kibana-plugin-core-server.asyncplugin.start.md)

## AsyncPlugin.start() method

<b>Signature:</b>

```typescript
start(core: CoreStart, plugins: TPluginsStart): TStart | Promise<TStart>;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| core | <code>CoreStart</code> | |
| plugins | <code>TPluginsStart</code> | |

<b>Returns:</b>

`TStart | Promise<TStart>`

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [kibana-plugin-core-server](./kibana-plugin-core-server.md) &gt; [AsyncPlugin](./kibana-plugin-core-server.asyncplugin.md) &gt; [stop](./kibana-plugin-core-server.asyncplugin.stop.md)

## AsyncPlugin.stop() method

<b>Signature:</b>

```typescript
stop?(): void;
```
<b>Returns:</b>
`void`
1 change: 1 addition & 0 deletions docs/development/core/server/kibana-plugin-core-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ The plugin integrates with the core system via lifecycle events: `setup`<!-- -->
| [AppCategory](./kibana-plugin-core-server.appcategory.md) | A category definition for nav links to know where to sort them in the left hand nav |
| [AssistanceAPIResponse](./kibana-plugin-core-server.assistanceapiresponse.md) | |
| [AssistantAPIClientParams](./kibana-plugin-core-server.assistantapiclientparams.md) | |
| [AsyncPlugin](./kibana-plugin-core-server.asyncplugin.md) | A plugin with asynchronous lifecycle methods. |
| [Authenticated](./kibana-plugin-core-server.authenticated.md) | |
| [AuthNotHandled](./kibana-plugin-core-server.authnothandled.md) | |
| [AuthRedirected](./kibana-plugin-core-server.authredirected.md) | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<b>Signature:</b>

```typescript
setup(core: CoreSetup, plugins: TPluginsSetup): TSetup | Promise<TSetup>;
setup(core: CoreSetup, plugins: TPluginsSetup): TSetup;
```

## Parameters
Expand All @@ -19,5 +19,5 @@ setup(core: CoreSetup, plugins: TPluginsSetup): TSetup | Promise<TSetup>;

<b>Returns:</b>

`TSetup | Promise<TSetup>`
`TSetup`

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<b>Signature:</b>

```typescript
start(core: CoreStart, plugins: TPluginsStart): TStart | Promise<TStart>;
start(core: CoreStart, plugins: TPluginsStart): TStart;
```

## Parameters
Expand All @@ -19,5 +19,5 @@ start(core: CoreStart, plugins: TPluginsStart): TStart | Promise<TStart>;

<b>Returns:</b>

`TStart | Promise<TStart>`
`TStart`

Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ The `plugin` export at the root of a plugin's `server` directory should conform
<b>Signature:</b>

```typescript
export declare type PluginInitializer<TSetup, TStart, TPluginsSetup extends object = object, TPluginsStart extends object = object> = (core: PluginInitializerContext) => Plugin<TSetup, TStart, TPluginsSetup, TPluginsStart>;
export declare type PluginInitializer<TSetup, TStart, TPluginsSetup extends object = object, TPluginsStart extends object = object> = (core: PluginInitializerContext) => Plugin<TSetup, TStart, TPluginsSetup, TPluginsStart> | AsyncPlugin<TSetup, TStart, TPluginsSetup, TPluginsStart>;
```
2 changes: 1 addition & 1 deletion packages/kbn-std/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export { get } from './get';
export { mapToObject } from './map_to_object';
export { merge } from './merge';
export { pick } from './pick';
export { withTimeout } from './promise';
export { withTimeout, isPromise } from './promise';
export { isRelativeUrl, modifyUrl, getUrlOrigin, URLMeaningfulParts } from './url';
export { unset } from './unset';
export { getFlattenedObject } from './get_flattened_object';
Expand Down
29 changes: 28 additions & 1 deletion packages/kbn-std/src/promise.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import { withTimeout } from './promise';
import { withTimeout, isPromise } from './promise';

const delay = (ms: number, resolveValue?: any) =>
new Promise((resolve) => setTimeout(resolve, ms, resolveValue));
Expand Down Expand Up @@ -50,3 +50,30 @@ describe('withTimeout', () => {
).rejects.toMatchInlineSnapshot(`[Error: from-promise]`);
});
});

describe('isPromise', () => {
it('returns true when arg is a Promise', () => {
expect(isPromise(Promise.resolve('foo'))).toEqual(true);
expect(isPromise(Promise.reject('foo').catch(() => undefined))).toEqual(true);
});

it('returns false when arg is not a Promise', () => {
expect(isPromise(12)).toEqual(false);
expect(isPromise('foo')).toEqual(false);
expect(isPromise({ hello: 'dolly' })).toEqual(false);
expect(isPromise([1, 2, 3])).toEqual(false);
});

it('returns false for objects with a non-function `then` property', () => {
expect(isPromise({ then: 'bar' })).toEqual(false);
});

it('returns false for null and undefined', () => {
expect(isPromise(null)).toEqual(false);
expect(isPromise(undefined)).toEqual(false);
});

it('returns true for Promise-Like objects', () => {
expect(isPromise({ then: () => 12 })).toEqual(true);
});
});
4 changes: 4 additions & 0 deletions packages/kbn-std/src/promise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ export function withTimeout<T>({
new Promise((resolve, reject) => setTimeout(() => reject(new Error(errorMessage)), timeout)),
]) as Promise<T>;
}

export function isPromise<T>(maybePromise: T | Promise<T>): maybePromise is Promise<T> {
return maybePromise ? typeof (maybePromise as Promise<T>).then === 'function' : false;
}
6 changes: 6 additions & 0 deletions packages/kbn-test/src/functional_tests/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ export async function runTests(options) {
try {
es = await runElasticsearch({ config, options: opts });
await runKibanaServer({ procs, config, options: opts });
// workaround until https://github.com/elastic/kibana/issues/89828 is addressed
await delay(5000);
await runFtr({ configPath, options: opts });
} finally {
try {
Expand Down Expand Up @@ -160,3 +162,7 @@ async function silence(log, milliseconds) {
)
.toPromise();
}

async function delay(ms) {
await new Promise((resolve) => setTimeout(resolve, ms));
}
Loading

0 comments on commit 3b3327d

Please sign in to comment.