Skip to content

Commit

Permalink
Unregister language server extension on LS shutdown
Browse files Browse the repository at this point in the history
fix eclipse-lemminx#605

Signed-off-by: Andrew Obuchowicz <[email protected]>
  • Loading branch information
AObuchow committed Feb 6, 2020
1 parent e8dd978 commit c4b7450
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@
import org.eclipse.lsp4xml.services.IXMLDocumentProvider;
import org.eclipse.lsp4xml.services.XMLLanguageService;
import org.eclipse.lsp4xml.settings.AllXMLSettings;
import org.eclipse.lsp4xml.settings.XMLCompletionSettings;
import org.eclipse.lsp4xml.settings.InitializationOptionsSettings;
import org.eclipse.lsp4xml.settings.LogsSettings;
import org.eclipse.lsp4xml.settings.ServerSettings;
import org.eclipse.lsp4xml.settings.SharedSettings;
import org.eclipse.lsp4xml.settings.XMLCodeLensSettings;
import org.eclipse.lsp4xml.settings.XMLCompletionSettings;
import org.eclipse.lsp4xml.settings.XMLFormattingOptions;
import org.eclipse.lsp4xml.settings.XMLGeneralClientSettings;
import org.eclipse.lsp4xml.settings.XMLSymbolSettings;
Expand Down Expand Up @@ -176,6 +176,7 @@ public synchronized void updateSettings(Object initializationOptionsSettings) {

@Override
public CompletableFuture<Object> shutdown() {
xmlLanguageService.dispose();
return computeAsync(cc -> new Object());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,14 @@ public <T> T getComponent(Class clazz) {

public void initializeParams(InitializeParams params) {
if (initialized) {
extensions.stream().forEach(extension -> extension.start(params, this));
extensions.stream().forEach(extension -> {
try {
extension.start(params, this);
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Error while starting extension <" + extension.getClass().getName() + ">",
e);
}
});
} else {
this.params = params;
}
Expand Down Expand Up @@ -169,7 +176,7 @@ public void initializeIfNeeded() {
}

private synchronized void initialize() {

if (initialized) {
return;
}
Expand All @@ -194,8 +201,22 @@ void registerExtension(IXMLExtension extension) {
}

void unregisterExtension(IXMLExtension extension) {
extensions.remove(extension);
extension.stop(this);
try {
extensions.remove(extension);
extension.stop(this);
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Error while stopping extension <" + extension.getClass().getName() + ">", e);
}
}

/**
* Unregisters all registered extensions.
*/
public void dispose() {
// Copy the list of extensions to avoid ConcurrentModificationError
List<IXMLExtension> extensionReferences = new ArrayList<>();
extensions.forEach(extensionReferences::add);
extensionReferences.forEach(this::unregisterExtension);
}

public void registerCompletionParticipant(ICompletionParticipant completionParticipant) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*******************************************************************************
* Copyright (c) 2020 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lsp4xml.services.extensions;

import static org.junit.Assert.assertTrue;

import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4xml.services.extensions.save.ISaveContext;
import org.junit.Test;

/**
* Ensures XML LS extensions are correctly unregistered when
* {@code XMLExtensionRegistry.dispose()} is called. During extension
* unregistration, the {@code IXMLExtension.stop()} function is called.
*
* @author aobuchow
*
*/
public class ExtensionRegistryDisposeTest {

@Test
public void testExtensionRegistryDipose() {
XMLExtensionsRegistry registry = new XMLExtensionsRegistry();
registry.initializeIfNeeded();
MockXMLExtension extension = new MockXMLExtension();
registry.registerExtension(extension);
assertTrue(!extension.isStopped());
registry.dispose();
assertTrue(extension.isStopped());
assertTrue(registry.getExtensions().isEmpty());
}
}

class MockXMLExtension implements IXMLExtension {
boolean stopped;

@Override
public void start(InitializeParams params, XMLExtensionsRegistry registry) {
stopped = false;
}

@Override
public void stop(XMLExtensionsRegistry registry) {
stopped = true;
}

@Override
public void doSave(ISaveContext context) {
}

public boolean isStopped() {
return stopped;
}

}

0 comments on commit c4b7450

Please sign in to comment.