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

How renderers handle extension code activation #130499

Closed
rebornix opened this issue Aug 10, 2021 · 10 comments
Closed

How renderers handle extension code activation #130499

rebornix opened this issue Aug 10, 2021 · 10 comments
Assignees
Labels
feature-request Request for new features or functionality notebook verification-needed Verification of issue is requested verified Verification succeeded
Milestone

Comments

@rebornix
Copy link
Member

rebornix commented Aug 10, 2021

Notebook renderers are usually contributed statically through contributions in package.json but we also allow communication between extension code and the renderers in the webview, through webview communication API. Having the ability to talk to the extension means that the renderer code might not be able to handle output rendering without some sort of setup in the extension host side, but this would degrade the file open experience as we don't want all renderers extensions to be activated prior to ipynb file opening.

To ensure a smooth file opening experience, VS Code will only wait for the serializer to be activated. This means extensions which contribute renderers will need to handle the activation/evaluation of extension code and renderer code properly.

@rebornix rebornix added feature-request Request for new features or functionality notebook labels Aug 10, 2021
@rchiodo
Copy link
Contributor

rchiodo commented Aug 10, 2021

Maybe have some sort of global event in the window that renderers can listen for? Like 'extension-loaded' or something?

@DonJayamanne
Copy link
Contributor

DonJayamanne commented Aug 18, 2021

Summary of discussion (recommended solution is Solution 3:

Problem:

  • Assume we have two extensions, renderer Extension R & and regular Extension A.
  • When a notebook is opened and output is renderers, renderer extension will get loaded and output displayed.
  • Renderer extension could send messages to extension host, however its possible the extension Extension A has not yet been activated, hence the message is never handled.

Solution 1

  • Assume it takes a few seconds for Extension A to get activated, the renderer Extension could send messages every 500ms for the next 10s, until it gets a response from Extension A.
  • Cons:
    • What's the frequency of these messages & how long should it keep sending these messages
    • Doesn't work well if there are multiple Extensions that need to communicate with Renderer

Solution 2

  • When renderer A sends a message to the extension host, VS Code could store this in some internal buffer.
  • When the extension A is up and running, VS Code could empty the buffer.
  • Cons:
    • What happens when we have Extension B that also wants to listen to messages. Do we re-play these messages to extension B as well. This could be incorrect in some situations as Extension B might not be interested in stale communication messages.
    • Other issues arising from unnecessarily buffering messages in vscode (unnecessarily chewing up resource by buffering)
    • What if the other extensions never activate?

Solution 3

  • When renderer Extension R is up and running, it will:
    • Broadcast (to extension host) the fact that it is up and running.
    • Listing to incoming messages from extension
  • Similarly, Extension A will:
    • Broadcast (to renderer) the fact that it is up and running.
    • Listing to incoming messages from renderer extension
  • This way, if we have another Extension B, it will be able to communicate with Renderer Extension R as well.
  • Cons:
    • The Extensions will need to come up with their own messages thats used to commence the handshake.

@rebornix
Copy link
Member Author

The solution 3 is always needed since currently extensions always need to create a messaging object https://github.com/microsoft/vscode/blob/main/src/vs/vscode.d.ts#L12356 to communicate with the renderers loaded in the notebook webview, since the extension code and the renderers are loaded in different processes, there is no guarantee which piece of code finish evaluation and execution first. In other words, if one wants to build a renderer which can talk to the extension part, a handshake is always required as there is no guarantee which code is ready first.

@rebornix
Copy link
Member Author

Summary of how one renderer extension would need to do to support communication between the renderer code in webview and extension code running in the extension host code.

For example, a renderer extension contributes a renderer renderer_a for mimetype application/vnd-sample. The renderer extension code are activated separately in two contexts

  1. Users open a notebook, which contain an output with mimetype application/vnd-sample.
  2. Extension code gets activated by onNotebook event.
    2.1 Create a communication object by const comm = vscode.notebooks.createRendererMessaging('renderer_a'). and use comm.postMessage and comm.onDidReceiveMessage
  3. Renderer code loaded in Notebook webview
    3.1 Users scroll the output into view
    3.2 Renderer code gets activated, and use context.postMessage and context.onDidReceiveMessage to communicate with the extension side

There is no guarantee when 2.1 or 3.2 is executed or in what sequence. We can see them as two processes and the code on each side talk to each other through { postMessage, onDidRecieveMessage }. Both sides should still work even if the other side is not ready yet or become unresponsive.

@rebornix rebornix added this to the August 2021 milestone Aug 19, 2021
@sandy081
Copy link
Member

@DonJayamanne May I know if this needs to be verified (if so add verification-needed label) or tested via test plan (if so add on-testplan label)?

@DonJayamanne
Copy link
Contributor

@sandy081 Sorry, the documentation needs to be udpated. Will work on that today.

@sandy081
Copy link
Member

Added verification-needed label. Please update it with on-testplan label if it is already tested through test plan items. Otherwise, please add steps to verify. Thanks.

@sandy081 sandy081 added the verification-steps-needed Steps to verify are needed for verification label Aug 26, 2021
@roblourens
Copy link
Member

I think the only change here is to docs, and so verification steps would be to read the change and see if it makes sense. Let me know @DonJayamanne if there was any code change that should be tested.

@roblourens roblourens removed the verification-steps-needed Steps to verify are needed for verification label Aug 26, 2021
@JacksonKearl JacksonKearl added the verified Verification succeeded label Aug 26, 2021
@DonJayamanne
Copy link
Contributor

DonJayamanne commented Aug 27, 2021

@roblourens thanks
Updated docs here microsoft/vscode-docs#4772
Got a subsequent PR (with more updates) here microsoft/vscode-docs#4782

@github-actions github-actions bot locked and limited conversation to collaborators Oct 3, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature-request Request for new features or functionality notebook verification-needed Verification of issue is requested verified Verification succeeded
Projects
None yet
Development

No branches or pull requests

7 participants
@roblourens @rebornix @DonJayamanne @JacksonKearl @sandy081 @rchiodo and others