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

Use separate thread to handle didChangeWatchedFiles events #2643

Merged
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ public class JDTLanguageServer extends BaseJDTLanguageServer implements Language
private LanguageServerWorkingCopyOwner workingCopyOwner;
private PreferenceManager preferenceManager;
private DocumentLifeCycleHandler documentLifeCycleHandler;
private WorkspaceEventsHandler workspaceEventHandler;
private WorkspaceDiagnosticsHandler workspaceDiagnosticsHandler;
private ClasspathUpdateHandler classpathUpdateHandler;
private JVMConfigurator jvmConfigurator;
Expand Down Expand Up @@ -241,6 +242,7 @@ public void connectClient(JavaLanguageClient client) {
pm.setConnection(client);
WorkingCopyOwner.setPrimaryBufferProvider(this.workingCopyOwner);
this.documentLifeCycleHandler = new DocumentLifeCycleHandler(this.client, preferenceManager, pm, true);
this.workspaceEventHandler = new WorkspaceEventsHandler(pm, this.client, this.documentLifeCycleHandler);
this.telemetryManager.setLanguageClient(client);
this.telemetryManager.setPreferenceManager(preferenceManager);
}
Expand Down Expand Up @@ -573,8 +575,7 @@ public void didChangeConfiguration(DidChangeConfigurationParams params) {
@Override
public void didChangeWatchedFiles(DidChangeWatchedFilesParams params) {
debugTrace(">> workspace/didChangeWatchedFiles ");
WorkspaceEventsHandler handler = new WorkspaceEventsHandler(pm, client, this.documentLifeCycleHandler);
handler.didChangeWatchedFiles(params);
this.workspaceEventHandler.didChangeWatchedFiles(params);
}

/* (non-Javadoc)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
package org.eclipse.jdt.ls.core.internal.handlers;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.concurrent.LinkedBlockingQueue;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
Expand Down Expand Up @@ -49,11 +48,23 @@ public class WorkspaceEventsHandler {
private final ProjectsManager pm;
private final JavaClientConnection connection;
private final BaseDocumentLifeCycleHandler handler;
private final LinkedBlockingQueue<FileEvent> queue = new LinkedBlockingQueue<>();

public WorkspaceEventsHandler(ProjectsManager projects, JavaClientConnection connection, BaseDocumentLifeCycleHandler handler) {
this.pm = projects;
this.connection = connection;
this.handler = handler;
Thread eventThread = new Thread(() -> {
while(true) {
try {
FileEvent event = queue.take();
handleFileEvent(event);
} catch (InterruptedException e) {
break;
}
}
}, "WorkspaceEventsHandler");
eventThread.start();
}

private CHANGE_TYPE toChangeType(FileChangeType vtype) {
Expand All @@ -70,50 +81,64 @@ private CHANGE_TYPE toChangeType(FileChangeType vtype) {
}

public void didChangeWatchedFiles(DidChangeWatchedFilesParams param) {
List<FileEvent> changes = param.getChanges().stream().distinct().collect(Collectors.toList());
for (FileEvent fileEvent : changes) {
CHANGE_TYPE changeType = toChangeType(fileEvent.getType());
if (changeType == CHANGE_TYPE.DELETED) {
cleanUpDiagnostics(fileEvent.getUri());
handler.didClose(new DidCloseTextDocumentParams(new TextDocumentIdentifier(fileEvent.getUri())));
discardWorkingCopies(fileEvent.getUri());
param.getChanges().stream().distinct().forEach(event -> {
try {
queue.put(event);
} catch (InterruptedException e) {
// do nothing
}
});
}

// for test only
public void handleFileEvents(FileEvent... fileEvents) {
for (FileEvent fileEvent : fileEvents) {
handleFileEvent(fileEvent);
}
}

private void handleFileEvent(FileEvent fileEvent) {
CHANGE_TYPE changeType = toChangeType(fileEvent.getType());
if (changeType == CHANGE_TYPE.DELETED) {
cleanUpDiagnostics(fileEvent.getUri());
handler.didClose(new DidCloseTextDocumentParams(new TextDocumentIdentifier(fileEvent.getUri())));
discardWorkingCopies(fileEvent.getUri());
}
ICompilationUnit unit = JDTUtils.resolveCompilationUnit(fileEvent.getUri());
if (unit != null && changeType == CHANGE_TYPE.CREATED && !unit.exists()) {
final ICompilationUnit[] units = new ICompilationUnit[1];
units[0] = unit;
try {
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
@Override
public void run(IProgressMonitor monitor) throws CoreException {
units[0] = createCompilationUnit(units[0]);
}
}, new NullProgressMonitor());
} catch (CoreException e) {
JavaLanguageServerPlugin.logException(e.getMessage(), e);
}
ICompilationUnit unit = JDTUtils.resolveCompilationUnit(fileEvent.getUri());
if (unit != null && changeType == CHANGE_TYPE.CREATED && !unit.exists()) {
final ICompilationUnit[] units = new ICompilationUnit[1];
units[0] = unit;
unit = units[0];
}
if (unit != null) {
if (unit.isWorkingCopy()) {
try {
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
@Override
public void run(IProgressMonitor monitor) throws CoreException {
units[0] = createCompilationUnit(units[0]);
}
}, new NullProgressMonitor());
IResource resource = unit.getUnderlyingResource();
if (resource != null && resource.exists()) {
resource.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
}
} catch (CoreException e) {
JavaLanguageServerPlugin.logException(e.getMessage(), e);
}
unit = units[0];
return;
}
if (unit != null) {
if (unit.isWorkingCopy()) {
try {
IResource resource = unit.getUnderlyingResource();
if (resource != null && resource.exists()) {
resource.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
}
} catch (CoreException e) {
JavaLanguageServerPlugin.logException(e.getMessage(), e);
}
continue;
}
if (changeType == CHANGE_TYPE.DELETED || changeType == CHANGE_TYPE.CHANGED) {
if (unit.equals(CoreASTProvider.getInstance().getActiveJavaElement())) {
CoreASTProvider.getInstance().disposeAST();
}
if (changeType == CHANGE_TYPE.DELETED || changeType == CHANGE_TYPE.CHANGED) {
if (unit.equals(CoreASTProvider.getInstance().getActiveJavaElement())) {
CoreASTProvider.getInstance().disposeAST();
}
}
pm.fileChanged(fileEvent.getUri(), changeType);
}
pm.fileChanged(fileEvent.getUri(), changeType);
}

private ICompilationUnit createCompilationUnit(ICompilationUnit unit) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ public class SyntaxLanguageServer extends BaseJDTLanguageServer implements Langu
public static final String JAVA_LSP_JOIN_ON_COMPLETION = "java.lsp.joinOnCompletion";

private SyntaxDocumentLifeCycleHandler documentLifeCycleHandler;
private WorkspaceEventsHandler workspaceEventHandler;
private ContentProviderManager contentProviderManager;
private ProjectsManager projectsManager;
private PreferenceManager preferenceManager;
Expand Down Expand Up @@ -261,6 +262,7 @@ public void initialized() {
public void connectClient(JavaLanguageClient client) {
super.connectClient(client);
this.documentLifeCycleHandler.setClient(this.client);
this.workspaceEventHandler = new WorkspaceEventsHandler(this.projectsManager, this.client, this.documentLifeCycleHandler);
}

@Override
Expand All @@ -279,8 +281,7 @@ public void didChangeConfiguration(DidChangeConfigurationParams params) {
@Override
public void didChangeWatchedFiles(DidChangeWatchedFilesParams params) {
logInfo(">> workspace/didChangeWatchedFiles ");
WorkspaceEventsHandler handler = new WorkspaceEventsHandler(this.projectsManager, this.client, this.documentLifeCycleHandler);
handler.didChangeWatchedFiles(params);
this.workspaceEventHandler.didChangeWatchedFiles(params);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ public void testChangeWorkingCopy() throws Exception {
File javaFile = new File(projectFile, "src/org/sample/Foo.java");
FileUtils.writeStringToFile(javaFile, source);
String uri = JDTUtils.toURI(unit);
DidChangeWatchedFilesParams params = new DidChangeWatchedFilesParams(Arrays.asList(new FileEvent(uri, FileChangeType.Changed)));
new WorkspaceEventsHandler(projectsManager, javaClient, lifeCycleHandler).didChangeWatchedFiles(params);
new WorkspaceEventsHandler(projectsManager, javaClient, lifeCycleHandler).handleFileEvents(new FileEvent(uri, FileChangeType.Changed));
waitForBackgroundJobs();
assertTrue(classFile.lastModified() > lastModified);
}
Expand All @@ -124,12 +123,11 @@ public void testDiscardStaleWorkingCopies() throws Exception {
File newPack = new File(oldPack.getParent(), "mynewpack");
Files.move(oldPack, newPack);
assertTrue(unit.isWorkingCopy());
DidChangeWatchedFilesParams params = new DidChangeWatchedFilesParams(Arrays.asList(
new WorkspaceEventsHandler(projectsManager, javaClient, lifeCycleHandler).handleFileEvents(
new FileEvent(newUri, FileChangeType.Created),
new FileEvent(parentUri, FileChangeType.Changed),
new FileEvent(oldUri, FileChangeType.Deleted)
));
new WorkspaceEventsHandler(projectsManager, javaClient, lifeCycleHandler).didChangeWatchedFiles(params);
);
assertFalse(unit.isWorkingCopy());
}

Expand All @@ -145,10 +143,7 @@ public void testDeleteProjectFolder() throws Exception {
assertTrue(module2.exists());

clientRequests.clear();
DidChangeWatchedFilesParams params = new DidChangeWatchedFilesParams(Arrays.asList(
new FileEvent(projectUri, FileChangeType.Deleted)
));
new WorkspaceEventsHandler(projectsManager, javaClient, lifeCycleHandler).didChangeWatchedFiles(params);
new WorkspaceEventsHandler(projectsManager, javaClient, lifeCycleHandler).handleFileEvents(new FileEvent(projectUri, FileChangeType.Deleted));
waitForBackgroundJobs();
assertFalse(module2.exists());

Expand Down