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

don't send plugin metadata over JSON-RPC #6233

Closed
wants to merge 2 commits into from
Closed

Conversation

akosyakov
Copy link
Member

@akosyakov akosyakov commented Sep 20, 2019

What it does

  • fix plugin system does not scale over JSON-RPC #6228:
    • don't send plugin metadata over JSON-RPC, see why and how here
    • don't send debugger contributions from the plugin host process to the frontend, but instead initially them statically from plugin metadata, see
  • update the changelog with a breaking change

How to test

  • remove native extension from the browse example and rebuild:
    • textmate grammar
    • debug-nodejs
    • java
    • java-debug
  • install 57 VS Code extensions in plugins folder:
    https://drive.google.com/file/d/1tuOsorMVOKi_twL9oAuZxgrD7-VUwNsj/view?usp=sharing
    • could not come up with a command to pull it from the gdrive in the terminal, if someone knows how to, please share
  • use system proxy to emulate slow connection, e.g. Charles proxy
    • you cannot do it in Chrome, since it cannot throttle web sockets
  • measure how long does it takes to activate all plugins before and after
  • observe whether you get yellow status bar and ws frames hangs for 20-30 seconds after and before
  • play with unstable connections to confirm that plugins get reloaded/unloaded on the reconnection

Review checklist

Reminder for reviewers

getDeployedFrontendMetadata(): Promise<PluginMetadata[]>;
getDeployedBackendMetadata(): Promise<PluginMetadata[]>;
getDeployedPlugins(): Promise<string[]>;
getDeployedPlugin(id: string): Promise<PluginMetadata | undefined>;
Copy link
Contributor

Choose a reason for hiding this comment

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

IMHO it looks strange to have same method which is not returning the same object
should be getDeployedMetadata for the second

Copy link
Member Author

Choose a reason for hiding this comment

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

Could you elaborate please? Is it about undefined? Do you mean that a plugin cannot be undeployed in the meantime?

@akosyakov akosyakov changed the title pull/push plugin metadata one by one don't send plugin metadata over web socket Sep 22, 2019
@akosyakov akosyakov changed the title don't send plugin metadata over web socket don't send plugin metadata over JSON-RPC Sep 22, 2019
Signed-off-by: Anton Kosiakov <anton.kosyakov@typefox.io>
So they are available eariler and not transfered twice to the frontend.

Signed-off-by: Anton Kosiakov <anton.kosyakov@typefox.io>
@akosyakov
Copy link
Member Author

akosyakov commented Sep 23, 2019

@eclipse-theia/plugin-system @svenefftinge Please have a look when you have time. With this PR, plugins loading should not block anymore. I did not have time to measure the startup time against previous state yet, will do later today or tomorrow.

I did 3 important changes:

  • serve plugin metadata only once to the frontend in the compressed form via an http endpoint, for 57 plugins size goes to 369kb instead of > 5mb
  • send to the plugin host process a plugin handle instead of the real plugin, the backend during dispatching a message inflate the handle to the real plugin
  • initialize debugger contributions from metadata, instead of sending it first to the plugin host and then back to the frontend (in this way plugin metadata used to be sent the second time from the backend to the frontend). Besides that it is slow and unnecessary, it was bogus to delay it till the plugin activation. cc @tolusha


$init(pluginInit: PluginInitData, configStorage: ConfigStorage): PromiseLike<void>;
/** initialize the manager, should be called only once */
$initiliaze(params: PluginManagerInitializeParams): Promise<void>;
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: initialize

@@ -619,11 +641,13 @@ export interface PluginDeployerHandler {
}

export const HostedPluginServer = Symbol('HostedPluginServer');
/**
* Don't expose plugin metadata via JSON-RPC. It is expensive to load and blocks the underlying connection.
* Instead use `/plugins` http endpoint, it serves compressed metadata for the give set of plugins.
Copy link
Contributor

Choose a reason for hiding this comment

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

typo: .. the given set of

}

reset(): void {
this._initialized = new Deferred<void>();
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we also generate a new id here, just to avoid confusion with previous connections?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it will be confusing if the same window will get different id on reconnect, e.g. you see that some plugin was disconnected for some client id, but then it gets immediately started for another client id without first loading it. I think it would be more consistent to see that a plugin was disconnected for such client and then started again for the same client.

Copy link
Contributor

@benoitf benoitf left a comment

Choose a reason for hiding this comment

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

I'm -1 about using separate connection for metadata.

AFAIK almost all metadata shouldn't be sent to the client. Changing the way on how to send them is not solving the root cause.

@akosyakov
Copy link
Member Author

@benoitf please elaborate on your suggestion, do you mean that the plugin model should be redesigned? How?

@akosyakov
Copy link
Member Author

akosyakov commented Sep 23, 2019

I will try to make an alternative version of a PR which relies on permessage-deflate or send compressed metadata over websocket. About permessage-deflate it seems that it is supported by Firefox and Chrome only, users of other browsers will have blocked UI.

@benoitf please let me know what do you think about first point in #6228 (comment) I would be glad to throw away raw package.json from metadata, it is probably will reduce compressed size to less than 200kb.

@benoitf
Copy link
Contributor

benoitf commented Sep 23, 2019

@akosyakov less than 200MB ?

@akosyakov
Copy link
Member Author

akosyakov commented Sep 23, 2019

@benoitf sorry, typo 😬 it should be kb

@benoitf
Copy link
Contributor

benoitf commented Sep 23, 2019

ok, better, thx

@akosyakov akosyakov deleted the ak/plugin_perf branch October 4, 2019 07:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

plugin system does not scale over JSON-RPC
3 participants