Revamp core environment class to support upcoming core<-->legacy bootstrap inversion.#21885
Conversation
src/core/server/config/env.ts
Outdated
There was a problem hiding this comment.
note: Kibana can rely on multiple configs at the same time (content will be merged).
src/core/server/config/env.ts
Outdated
There was a problem hiding this comment.
note: taken from
kibana/src/server/config/config.js
Lines 110 to 111 in 304a9f6
src/core/server/http/http_server.ts
Outdated
There was a problem hiding this comment.
note: we don't use these options in this PR yet, but we'll need them in the upcoming PRs (these are being passed to the legacy Hapi server so that we don't duplicate connection options like that https://github.com/elastic/kibana/blob/master/src/server/http/index.js#L33-L61 anymore).
There was a problem hiding this comment.
note: in the upcoming PRs, it will be detected like that: https://github.com/elastic/kibana/pull/19994/files#diff-806634e0e6f42d8ea73cd3565c9089cbR34 (and this function will go away completely)
There was a problem hiding this comment.
note: I added few more events (e.g. upgrade) to support socket.io functionality that Canvas uses.
There was a problem hiding this comment.
note: this will be moved into legacy_service in the upcoming PRs.
e9921c5 to
5816f36
Compare
…tstrap inversion.
5816f36 to
be9aa6c
Compare
| * @internal | ||
| */ | ||
| constructor(readonly homeDir: string, options: EnvOptions) { | ||
| this.configDir = resolve(this.homeDir, 'config'); |
There was a problem hiding this comment.
note: these corePluginsDir, logDir and staticFilesDir are properties that we can get rid of for now and add back when we really need them, I just preserved them since new-platform branch. Let me know if you want me to remove them.
💚 Build Succeeded |
|
👍 taking a look now |
| */ | ||
|
|
||
| /* tslint:disable max-classes-per-file */ | ||
|
|
There was a problem hiding this comment.
While you're in here, would you mind moving these test files out of the __tests__ directory? These should be right next to the files they are testing right?
There was a problem hiding this comment.
These should be right next to the files they are testing right?
Correct, __tests__ are still used everywhere in src/core/server as it was in new-platform branch. I was planning to get rid of all __tests__ from src/core/server in a dedicated PR, but can do it gradually in every PR that touches tests, like here. Will remove all __tests__ that I touch in this PR.
There was a problem hiding this comment.
Oh, no, I realized it will be a rebase nightmare for me since I have 3 more PRs based on this one that change these tests :/ Would you mind I prepare a dedicated PR to get rid of all __tests__ in src/core/server right after #22190?
| this.logDir = resolve(this.homeDir, 'log'); | ||
| this.staticFilesDir = resolve(this.homeDir, 'ui'); | ||
| } | ||
| public readonly packageInfo: Readonly<PackageInfo>; |
There was a problem hiding this comment.
Do you think maybe we want to use RecursiveReadOnly and something like https://github.com/elastic/kibana/blob/743edc6c0e696f861aab98fd3172619914459a70/src/core/public/injected_metadata/deep_freeze.ts?
There was a problem hiding this comment.
Hmm, we have only one level of nesting here, but we can still use RecursiveReadOnly and deep_freeze. How do you see sharing this function between server and public?
There was a problem hiding this comment.
It's been pretty common for plugins to use /public, /server, and /common directories for this type of thing... What do you think @epixa?
There was a problem hiding this comment.
Okay, I don't want to block on this one for too long, so I moved deep_freeze into src/core/utils that we have already for other similar things and started to use it src/core/server/config/env. We can rename it to common or whatever once/if we want to in the future PRs without any problem.
There was a problem hiding this comment.
Hah, sharing code between client and server turned out to be not that easy as I thought :) Ugh
There was a problem hiding this comment.
We discussed that with @spalger on Slack and agreed that it'd make sense to work on a proper solution for the code that is shared between core server and core public in a separate PR. So I've reverted my latest commit.
| prod: !this.cliArgs.dev, | ||
| }); | ||
|
|
||
| const isKibanaDistributable = pkg.build && pkg.build.distributable === true; |
There was a problem hiding this comment.
We'll need env.isDistributable at some point, but I guess we can expose it once we need it.
There was a problem hiding this comment.
Yep, let's expose it when we need it.
|
|
||
| private getDefaultConfigFile() { | ||
| return resolve(this.configDir, 'kibana.yml'); | ||
| this.legacy = new EventEmitter(); |
There was a problem hiding this comment.
this will be moved into legacy_service in the upcoming PRs.
I'm pretty sure that means this legacy "chanel" is temporary, right? When we get rid of it will the LegacyService just be able to talk to the HttpService and get a promise/observable for the server connection rather than using an EventEmitter on the Env?
There was a problem hiding this comment.
Yes, my plan is to get rid of it in #22190. I still don't like any approach to be honest since I don't want to pass internal server reference around and be a part of any public contract :/ But there is no other choice for now.
| isDevClusterMaster: true, | ||
| }); | ||
|
|
||
| expect(Object.entries(defaultEnv)).toMatchSnapshot('env properties'); |
There was a problem hiding this comment.
Why can't this just check expect(defaultEnv).toMatchSnapshot()? Doesn't Object.entries() make this sensitive to property ordering? I certainly think it makes the snapshots harder to grok. If it has to do with hidden properties or something maybe expect({ ...defaultEnv }).toMatchSnapshot() would be a slightly better choice?
There was a problem hiding this comment.
Why can't this just check expect(defaultEnv).toMatchSnapshot()?
Hmm, we can, I have no idea why I have these Object.entries 🙈
|
|
||
| expect(listener).toHaveBeenCalledTimes(2); | ||
| expect(listener).toHaveBeenCalledWith(1, 2, 3, 4); | ||
| expect(listener).toHaveBeenCalledWith(5, 6, 7, 8); |
There was a problem hiding this comment.
Did you mean to remove this assertion?
| return [ | ||
| eventName, | ||
| (...args: any[]) => { | ||
| // Since it's just a proxy and the underlying server is managed by the core |
There was a problem hiding this comment.
Hmm, what inspired this change? I feel like the default behavior of falling over when something isn't listening for the error event is generally desired, but this now listens for that event and swallows it if nothing else is listening for it...
There was a problem hiding this comment.
I think I was hit by this during testing/development at some point, when core http server failed before legacy Kibana subscribed to the proxifier events. So the original error has been handled by Hapi 17 and core, but nothing was listening for the "forwarded" error event so we got unhandled exception.
Legacy Kibana only attaches error handler when Hapi starts to listen so it may take some time.
What do you think?
There was a problem hiding this comment.
I think I need more time to think this through, and maybe we could chat about it, but I think if something fails before legacy Kibana server attaches its error handler we probably shouldn't be swallowing it and ignoring it.
There was a problem hiding this comment.
Okay, I'll remove it then and we'll see how it goes.
There was a problem hiding this comment.
Removed ✔️ We can get back to it if it becomes a problem.
💔 Build Failed |
|
retest |
💔 Build Failed |
💔 Build Failed |
|
retest |
💔 Build Failed |
|
Have no idea why x-pack job is failing with |
💚 Build Succeeded |
💚 Build Succeeded |
… should be frozen.
💔 Build Failed |
…ops that should be frozen.
💚 Build Succeeded |
|
I think PR is ready for another pass @spalger, thanks! |
|
6.x/6.5: 35c081c |
After #19994
envwill store some additional data (e.g.cliArgs) that are required by the "legacy" Kibana, so in this PR I revampedenvclass to support that.I'm also experimenting with the new way of passing data (
env.legacybroadcast channel) from almost any place in the core to the legacy world: e.g. connection options fromRoot -> Server -> HttpModule -> HttpService -> HttpServeror anything else we may need in the future to glue core and the "legacy" Kibana.I found
env.legacyto be the easiest way to do that, not ideal though. So if you have any better ideas I'm all ears!Blocked by #21879Unblocks #19994