Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core/ui] bootstrap the legacy platform within the new platform #20699

Merged
merged 37 commits into from
Jul 18, 2018

Conversation

spalger
Copy link
Contributor

@spalger spalger commented Jul 11, 2018

Fixes #20694

Implements super basic new platform core system, which includes two services: core.injectedMetadata and core.legacyPlatform. The core currently has two responsibilities:

  1. read the metadata from the DOM and initialize the ui/metadata module with legacy metadata, proving out how we plan to expose data from the new platform through the existing APIs/modules to the legacy platform.
  2. bootstrap the legacy platform by loading either ui/chrome or ui/test_harness

Because core mutates the ui/metadata module before bootstrapping the legacy platform all existing consumers of ui/metadata won't be impacted by the fact that metadata loading was moved into the new platform. We plan to do this for many other services that will need to exist in both the legacy and new platforms, like ui/chrome (see #20696).

@spalger spalger added WIP Work in progress Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.0.0 v6.4.0 labels Jul 11, 2018
injectedMetadataForTesting: {
legacyMetadata
}
}).initLegacyPlatform(() => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The convention we've talked about is having a core start function and then invoking legacy startup/bootstrap through a legacy service within the core system. This way we can identify precisely when the legacy code kicks off in the context of all the new platform services we'd be rolling out.

Is there a reason we need to abandon that approach for this initLegacyPlatform approach?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, happy to move it there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just didn't want to worry about start()/stop() right now, but it's not a big deal.

@elasticmachine

This comment has been minimized.

import { InjectedMetadataService } from '../injected_metadata';

interface Deps {
injectedMetadata: ReturnType<InjectedMetadataService['start']>;
Copy link
Contributor Author

@spalger spalger Jul 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really not sure what to name this type, but once we get plugins in the mix we will probably want to export a named type they can use to define the dependencies of their start functions... InjectedMetadataContract? InjectedMetadataStartContract? StartedInjectedMetadata...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InjectedMetadataStartContract works for me. I never really intended the word "contract" to be codified, but if that's the language we're using when we talk about this thing, we might as well just write it that way as well.

@elasticmachine

This comment has been minimized.

@elasticmachine

This comment has been minimized.

@spalger spalger force-pushed the implement/new-platform-bootstrap branch from d1bcd06 to 4f8fe21 Compare July 12, 2018 21:58
@spalger spalger force-pushed the implement/new-platform-bootstrap branch from 4bfb104 to 5357110 Compare July 12, 2018 22:03
@spalger
Copy link
Contributor Author

spalger commented Jul 12, 2018

@epixa this is ready for another look

@elasticmachine

This comment has been minimized.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Copy link
Contributor

@epixa epixa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes here look good, and I spun up Kibana and clicked around, everything seemed unaffected by this change as we'd expect.

This all needs unit tests though.

@@ -100,16 +100,22 @@ describe('constructor', () => {
});

describe('#start()', () => {
it('calls lifecycleSystem#start() and injectedMetadata#start()', () => {
const core = new CoreSystem({
let core;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought you were the one in particular that hated this pattern and wanted everyone to use setup functions instead!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha, I do, but setup functions are best because they take arguments, when there aren't any arguments I'm not super picky. But point taken!

Copy link
Contributor Author

@spalger spalger Jul 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also the issue that the mocks are cleared between each test, so starting core once and reusing the value for each test wouldn't work anyway.

@epixa
Copy link
Contributor

epixa commented Jul 16, 2018

Still LGTM

@spalger spalger force-pushed the implement/new-platform-bootstrap branch from 127ef04 to 3e5a2ab Compare July 16, 2018 22:54
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@epixa
Copy link
Contributor

epixa commented Jul 17, 2018

And still LGTM

Copy link
Member

@azasypkin azasypkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good to me, just few nits and questions. Running PR locally and approve it after a smoke test :)

@@ -66,8 +64,8 @@ export default (kibana) => {

// add the modules from all of this plugins apps
for (const app of uiApps) {
if (app.getPluginId() === pluginId) {
modules = union(modules, app.getModules());
if (app.getPluginId() === pluginId && !modules.includes(app.getMainModuleId())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional nit: if we use const modules = new Set() we won't need this !....includes checks (that we can accidentally forget about if we decide to add new for for some reason). The only cons is that we'll have to do modules: [...modules] or Array.from(modules) later.

@@ -22,5 +22,5 @@ import { ToolingLog } from '@kbn/dev-utils';
import { File } from '../file';

export function pickFilesToLint(log: ToolingLog, files: File[]) {
return files.filter(file => file.isTypescript());
return files.filter(file => file.isTypescript() && !file.isFixture());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: what issues do we have without this? Can't we have nice linted fixtures? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue this is that the fixture files are excluded from our main TS project because they can (and in my case need to) include invalid typescript for the purpose of making sure our types impose certain limitations. Since the files are not a part of a TS project they fail the pre-commit hook since TSLint needs the project file for a specific file to run the type-aware checks.

It's possible that we could run fixtures through a linting phase that isn't type enabled, but I'd rather do that in a separate PR. See #20910

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, got it, thanks for explanation.

useLegacyTestHarness?: LegacyPlatformParams['useLegacyTestHarness'];
}

export class CoreSystem {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: would be really great if you can add a top level comment for CoreSystem explaining what its role and what it's supposed to do.

* under the License.
*/

type Freezable = { [k: string]: any } | any[];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: hmm, | any[] - is it really supposed to work for arrays as expected? I don't see any test that would check that case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Object.freeze works just fine on arrays, but you're right that there are not tests for this. I'll add them.

};
}

export class InjectedMetadataService {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: could you please add a top level comment for this service as well?


it('calls injectedMetadata#start()', () => {
startCore();
expect(MockInjectedMetadataService.mock.instances[0].start).toHaveBeenCalledTimes(1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional nit: maybe destructuring can make it a little bit more readable: const [mockInstance] = MockInjectedMetadataService.mock.instances;

body(kbn-chrome, id='#{appName}-body')
kbn-initial-state(data=JSON.stringify(kibanaPayload))
body
kbn-injected-metadata(data=JSON.stringify(injectedMetadata))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can you please also remove the last kbn-initial-state occurrence from

'<div><div id="editor" /><div id="editor_actions" /><div id="copy_as_curl" /><kbn-initial-state data="{}"/></div>';
and update comment here
"description": "When using the state:storeInSessionStorage setting with the short-urls, we need some way to get the full URL's hashed states into sessionStorage, this app will grab the URL from the kbn-initial-state and and put the URL hashed states into sessionStorage before redirecting the user."
?

getModules() {
return this._main ? [this._main] : [];
getMainModuleId() {
return this._main;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

await fcb(cb => unlink(this.getOutputPath(), cb));
} catch (e) {
return null;
async isCacheValid() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: while you're here, would you mind adding comment for isCacheValid explaining how it works exactly?

@@ -28,7 +28,7 @@ export const UI_EXPORT_DEFAULTS = {

webpackAliases: {
ui: resolve(ROOT, 'src/ui/public'),
ui_framework: resolve(ROOT, 'ui_framework'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: btw, not related to this PR, do we still need ui_framework here

ui_framework: fromKibana('ui_framework'),
?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I don't think so.

Copy link
Member

@azasypkin azasypkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally in dev and non-dev modes, haven't noticed anything suspicious.

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@spalger spalger merged commit 8662475 into elastic:master Jul 18, 2018
spalger pushed a commit to spalger/kibana that referenced this pull request Jul 18, 2018
…tic#20699)

Fixes elastic#20694

Implements super basic new platform `core` system, which includes two services: `core.injectedMetadata` and `core.legacyPlatform`. The `core` currently has two responsibilities:

 1. read the metadata from the DOM and initialize the `ui/metadata` module with legacy metadata, proving out how we plan to expose data from the new platform through the existing APIs/modules to the legacy platform.
 2. bootstrap the legacy platform by loading either `ui/chrome` or `ui/test_harness`

Because `core` mutates the `ui/metadata` module before bootstrapping the legacy platform all existing consumers of `ui/metadata` won't be impacted by the fact that metadata loading was moved into the new platform. We plan to do this for many other services that will need to exist in both the legacy and new platforms, like `ui/chrome` (see elastic#20696).
spalger pushed a commit that referenced this pull request Jul 18, 2018
…) (#20913)

Fixes #20694

Implements super basic new platform `core` system, which includes two services: `core.injectedMetadata` and `core.legacyPlatform`. The `core` currently has two responsibilities:

 1. read the metadata from the DOM and initialize the `ui/metadata` module with legacy metadata, proving out how we plan to expose data from the new platform through the existing APIs/modules to the legacy platform.
 2. bootstrap the legacy platform by loading either `ui/chrome` or `ui/test_harness`

Because `core` mutates the `ui/metadata` module before bootstrapping the legacy platform all existing consumers of `ui/metadata` won't be impacted by the fact that metadata loading was moved into the new platform. We plan to do this for many other services that will need to exist in both the legacy and new platforms, like `ui/chrome` (see #20696).
@spalger
Copy link
Contributor Author

spalger commented Jul 18, 2018

6.4/6.x: 360c50b

@spalger spalger deleted the implement/new-platform-bootstrap branch July 18, 2018 06:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:New Platform review Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v6.4.0 v7.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants