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

[output][vscode][plugin] Output channels are not cleaned up after closing the channel #8122

Closed
kittaakos opened this issue Jul 1, 2020 · 9 comments · Fixed by #8476
Closed
Labels
bug bugs found in the application output issues related to the output plug-in system issues related to the plug-in system vscode issues related to VSCode compatibility

Comments

@kittaakos
Copy link
Contributor

Bug Description:

The output channel registry for the extensions (VS Code and Theia plug-in) does its own caching:

this.channels.set(channelName, outputChannel);

Disposing the channel on the FE does not update the channel cache for the extensions, and tries to work on a disposed editor model.

textModel.ts:360 Uncaught (in promise) Error: Model is disposed!
    at TextModel._assertNotDisposed (textModel.ts:360)
    at TextModel.getLineCount (textModel.ts:739)
    at OutputChannel.<anonymous> (output-channel.ts:422)
    at step (output-channel.ts:15)
    at Object.next (output-channel.ts:15)
    at fulfilled (output-channel.ts:15)

Steps to Reproduce:

  1. Start a channel from an extension: const c = (theia|vscode).window.createOutputChannel('test-channel'); c.appendLine('running...');
  2. Close the channel with the Output: Close Output Channel... command.
  3. Repeat step 1.

Additional Information

  • Operating System:
  • Theia Version:
@kittaakos kittaakos added bug bugs found in the application plug-in system issues related to the plug-in system vscode issues related to VSCode compatibility output issues related to the output labels Jul 1, 2020
@mikael-desharnais
Copy link
Contributor

mikael-desharnais commented Jul 2, 2020

Adding the following code to the registry would solve the issue :

@postConstruct()
    init(): void {
        this.outputChannelManager.onChannelDeleted((channel) => {
            if (this.channels.has(channel.name)) {
                this.channels.delete(channel.name);
            }
        })
    }

But That would not remove the cache done by the registry just managing it properly ?
Could anyone provide an opinion on which solution would be better ?

@kittaakos
Copy link
Contributor Author

Could anyone provide an opinion on which solution would be better ?

Why do we need to cache it?

@mikael-desharnais
Copy link
Contributor

Reading code, it does not seem that the caching is usefull (this.channels is private) so removing the cache and using this.outputChannelManager.getChannel all the time should not be an issue

@kittaakos
Copy link
Contributor Author

Reading code, it does not seem that the caching is usefull (this.channels is private) so removing the cache and using this.outputChannelManager.getChannel all the time should not be an issue

Exactly, I do not see any reason for caching here. The OutputChannelManager manages the channels.

@mikael-desharnais
Copy link
Contributor

Can you propose a pull request ? At the moment, I'm cannot provide one.
Otherwise, I will provide one in a few days

@kittaakos
Copy link
Contributor Author

Otherwise, I will provide one in a few days

The fix is not urgent, it can wait for you ;) Let me know if you're interested in helping us. I can provide you a few pointers for the PR. Otherwise, we will fix this later.

mikael-desharnais added a commit to mikael-desharnais/theia that referenced this issue Jul 3, 2020
eclipse-theia#8122
Signed-off-by: Mikael Desharnais <mikael.desharnais@gmail.com>
@mikael-desharnais
Copy link
Contributor

Just to comment on this, there is one drawback to deleting the cache.
The getChannel method of the outputChannelManager returns an existing channel if there is one or creates one if there is none. This method always provides a channel.
Using the cache can prevent the creation of a new channel in the case where someone tries to hide a channel that does not exist.
In this case : this.outputChannelManager.getChannel("Not existing").setVisibility(false), a new channel would be created.
To me, the real problem is the implementation of the OutputChannelManager, the getChannel method should only return existing channels and throw an exception if no channel exists by this name.
There should be a few more methods for this class : hasChannel & createChannel. That would make the code clearer and prevent useless creations of channels.

@kittaakos
Copy link
Contributor Author

The getChannel method of the outputChannelManager returns an existing channel if there is one or creates one if there is none. This method always provides a channel.

Correct and this is the expected behavior.

Using the cache can prevent the creation of a new channel in the case where someone tries to hide a channel that does not exist.

I do not understand this. Hiding a channel is not removal, we just do not show it in the UI.

In this case : this.outputChannelManager.getChannel("Not existing").setVisibility(false), a new channel would be created.

This is also expected.

the getChannel method should only return existing channels and throw an exception if no channel exists by this name.

Well, we won't break this behavior.

There should be a few more methods for this class : hasChannel & createChannel. That would make the code clearer and prevent useless creations of channels.

Feel free to propose additional APIs, and we will look into your PR, but we cannot change the getChannel behavior.

@mikael-desharnais
Copy link
Contributor

Ok, if we can't break this behavior, I think we can remove all the if (channel) that clutter the registry and can never be false.

kittaakos pushed a commit that referenced this issue Sep 7, 2020
Instead of keeping an extra cache of channels for VS Code extensions,
we delegate the channel  manager one via commands.

Closes #8122

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
kittaakos pushed a commit that referenced this issue Sep 15, 2020
Instead of keeping an extra cache of channels for VS Code extensions,
we delegate the channel  manager one via commands.

Closes #8122

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug bugs found in the application output issues related to the output plug-in system issues related to the plug-in system vscode issues related to VSCode compatibility
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants