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

[dev/server] improve startup time and prevent OOMs on shutdown #78710

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion scripts/kibana.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@
*/

require('../src/apm')(process.env.ELASTIC_APM_PROXY_SERVICE_NAME || 'kibana-proxy');
require('../src/setup_node_env');
require('../src/setup_node_env/prebuilt_dev_only_entry');
require('../src/setup_node_env/babel_register')({
cache: false,
});
require('../src/cli/cli');
2 changes: 1 addition & 1 deletion scripts/precommit_hook.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
* under the License.
*/

require('../src/setup_node_env/babel_register');
require('../src/setup_node_env/babel_register')();
require('../src/dev/run_precommit_hook');
2 changes: 1 addition & 1 deletion src/cli/cluster/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export class Worker extends EventEmitter {
this.processBinder = new BinderFor(process);

this.env = {
NODE_OPTIONS: process.env.NODE_OPTIONS || '',
NODE_OPTIONS: process.env.NODE_OPTIONS || '--max-old-space-size=4096',
kbnWorkerType: this.type,
kbnWorkerArgv: JSON.stringify([...(opts.baseArgv || baseArgv), ...(opts.argv || [])]),
};
Expand Down
18 changes: 12 additions & 6 deletions src/core/server/plugins/plugins_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import Path from 'path';
import { Observable } from 'rxjs';
import { Observable, EMPTY } from 'rxjs';
import { filter, first, map, mergeMap, tap, toArray } from 'rxjs/operators';
import { pick } from '@kbn/std';

Expand Down Expand Up @@ -86,9 +86,11 @@ export class PluginsService implements CoreService<PluginsServiceSetup, PluginsS
private readonly config$: Observable<PluginsConfig>;
private readonly pluginConfigDescriptors = new Map<PluginName, PluginConfigDescriptor>();
private readonly uiPluginInternalInfo = new Map<PluginName, InternalPluginInfo>();
private readonly discoveryDisabled: boolean;

constructor(private readonly coreContext: CoreContext) {
this.log = coreContext.logger.get('plugins-service');
this.discoveryDisabled = coreContext.env.isDevClusterMaster;
this.pluginsSystem = new PluginsSystem(coreContext);
this.configService = coreContext.configService;
this.config$ = coreContext.configService
Expand All @@ -97,13 +99,17 @@ export class PluginsService implements CoreService<PluginsServiceSetup, PluginsS
}

public async discover({ environment }: PluginsServiceDiscoverDeps) {
this.log.debug('Discovering plugins');

const config = await this.config$.pipe(first()).toPromise();

const { error$, plugin$ } = discover(config, this.coreContext, {
uuid: environment.instanceUuid,
});
const { error$, plugin$ } = this.discoveryDisabled
? {
error$: EMPTY,
plugin$: EMPTY,
}
: discover(config, this.coreContext, {
uuid: environment.instanceUuid,
});

await this.handleDiscoveryErrors(error$);
await this.handleDiscoveredPlugins(plugin$);

Expand Down
6 changes: 4 additions & 2 deletions src/setup_node_env/babel_register/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,7 @@
// register and polyfill need to happen in this
// order and in separate files. Checkout each file
// for a much more detailed explanation
require('./register');
require('./polyfill');
module.exports = function (options) {
require('./register')(options);
require('./polyfill');
};
117 changes: 67 additions & 50 deletions src/setup_node_env/babel_register/register.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,59 +19,76 @@

var resolve = require('path').resolve;

// this must happen before `require('@babel/register')` and can't be changed
// once the module has been loaded
if (!process.env.BABEL_CACHE_PATH) {
process.env.BABEL_CACHE_PATH = resolve(
__dirname,
'../../../data/optimize/.babel_register_cache.json'
);
}
module.exports = function (options) {
options = options || {};

// paths that @babel/register should ignore
var ignore = [
/[\/\\]bower_components[\/\\]/,
/[\/\\]kbn-pm[\/\\]dist[\/\\]/,
// this must happen before `require('@babel/register')` and can't be changed
// once the module has been loaded
if (!process.env.BABEL_CACHE_PATH) {
process.env.BABEL_CACHE_PATH = resolve(
__dirname,
'../../../data/optimize/.babel_register_cache.json'
);
}

// TODO: remove this and just transpile plugins at build time, but
// has tricky edge cases that will probably require better eslint
// restrictions to make sure that code destined for the server/browser
// follows respects the limitations of each environment.
//
// https://github.com/elastic/kibana/issues/14800#issuecomment-366130268
// paths that @babel/register should ignore
var ignore = [
/[\/\\]bower_components[\/\\]/,
/[\/\\]kbn-pm[\/\\]dist[\/\\]/,

// ignore paths matching `/node_modules/{a}/{b}`, unless `a`
// is `x-pack` and `b` is not `node_modules`
/[\/\\]node_modules[\/\\](?!x-pack[\/\\](?!node_modules)([^\/\\]+))([^\/\\]+[\/\\][^\/\\]+)/,
// TODO: remove this and just transpile plugins at build time, but
// has tricky edge cases that will probably require better eslint
// restrictions to make sure that code destined for the server/browser
// follows respects the limitations of each environment.
//
// https://github.com/elastic/kibana/issues/14800#issuecomment-366130268

// ignore paths matching `/canvas/canvas_plugin/`
/[\/\\]canvas[\/\\]canvas_plugin[\/\\]/,
];
// ignore paths matching `/node_modules/{a}/{b}`, unless `a`
// is `x-pack` and `b` is not `node_modules`
/[\/\\]node_modules[\/\\](?!x-pack[\/\\](?!node_modules)([^\/\\]+))([^\/\\]+[\/\\][^\/\\]+)/,

if (global.__BUILT_WITH_BABEL__) {
// when building the Kibana source we replace the statement
// `global.__BUILT_WITH_BABEL__` with the value `true` so that
// when @babel/register is required for the first time by users
// it will exclude kibana's `src` directory.
//
// We still need @babel/register for plugins though, we've been
// building their server code at require-time since version 4.2
// TODO: the plugin install process could transpile plugin server code...
ignore.push(resolve(__dirname, '../../../src'));
} else {
ignore.push(
// ignore any path in the packages, unless it is in the package's
// root `src` directory, in any test or __tests__ directory, or it
// ends with .test.js, .test.ts, or .test.tsx
/[\/\\]packages[\/\\](eslint-|kbn-)[^\/\\]+[\/\\](?!src[\/\\].*|(.+[\/\\])?(test|__tests__)[\/\\].+|.+\.test\.(js|ts|tsx)$)(.+$)/
);
}
// ignore paths matching `/canvas/canvas_plugin/`
/[\/\\]canvas[\/\\]canvas_plugin[\/\\]/,
];

// modifies all future calls to require() to automatically
// compile the required source with babel
require('@babel/register')({
ignore,
babelrc: false,
presets: [require.resolve('@kbn/babel-preset/node_preset')],
extensions: ['.js', '.ts', '.tsx'],
});
if (global.__BUILT_WITH_BABEL__) {
// when building the Kibana source we replace the statement
// `global.__BUILT_WITH_BABEL__` with the value `true` so that
// when @babel/register is required for the first time by users
// it will exclude kibana's `src` directory.
//
// We still need @babel/register for plugins though, we've been
// building their server code at require-time since version 4.2
// TODO: the plugin install process could transpile plugin server code...
ignore.push(resolve(__dirname, '../../../src'));
} else {
ignore.push(
// ignore any path in the packages, unless it is in the package's
// root `src` directory, in any test or __tests__ directory, or it
// ends with .test.js, .test.ts, or .test.tsx
/[\/\\]packages[\/\\](eslint-|kbn-)[^\/\\]+[\/\\](?!src[\/\\].*|(.+[\/\\])?(test|__tests__)[\/\\].+|.+\.test\.(js|ts|tsx)$)(.+$)/
);
}

// prevent @babel/register from loading cache on require by setting env var
var clearBabelCacheEnvVar = false;
if (options.cache === false) {
clearBabelCacheEnvVar = true;
process.env.BABEL_DISABLE_CACHE = 'true';
}

// modifies all future calls to require() to automatically
// compile the required source with babel
require('@babel/register')({
ignore,
cache: options.cache !== false,
babelrc: false,
presets: [require.resolve('@kbn/babel-preset/node_preset')],
extensions: ['.js', '.ts', '.tsx'],
});

// clear the disable cache env var if we set it to prevent cache loading
if (clearBabelCacheEnvVar) {
delete process.env.BABEL_DISABLE_CACHE;
}
};
2 changes: 1 addition & 1 deletion src/setup_node_env/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@
*/

require('./prebuilt_dev_only_entry');
require('./babel_register');
require('./babel_register')();