Skip to content

Commit e5a9069

Browse files
Use separate thread to handle didChangeWatchedFiles events (#2643)
1 parent 4be2740 commit e5a9069

File tree

4 files changed

+72
-50
lines changed

4 files changed

+72
-50
lines changed

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/JDTLanguageServer.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ public class JDTLanguageServer extends BaseJDTLanguageServer implements Language
171171
private LanguageServerWorkingCopyOwner workingCopyOwner;
172172
private PreferenceManager preferenceManager;
173173
private DocumentLifeCycleHandler documentLifeCycleHandler;
174+
private WorkspaceEventsHandler workspaceEventHandler;
174175
private WorkspaceDiagnosticsHandler workspaceDiagnosticsHandler;
175176
private ClasspathUpdateHandler classpathUpdateHandler;
176177
private JVMConfigurator jvmConfigurator;
@@ -241,6 +242,7 @@ public void connectClient(JavaLanguageClient client) {
241242
pm.setConnection(client);
242243
WorkingCopyOwner.setPrimaryBufferProvider(this.workingCopyOwner);
243244
this.documentLifeCycleHandler = new DocumentLifeCycleHandler(this.client, preferenceManager, pm, true);
245+
this.workspaceEventHandler = new WorkspaceEventsHandler(pm, this.client, this.documentLifeCycleHandler);
244246
this.telemetryManager.setLanguageClient(client);
245247
this.telemetryManager.setPreferenceManager(preferenceManager);
246248
}
@@ -573,8 +575,7 @@ public void didChangeConfiguration(DidChangeConfigurationParams params) {
573575
@Override
574576
public void didChangeWatchedFiles(DidChangeWatchedFilesParams params) {
575577
debugTrace(">> workspace/didChangeWatchedFiles ");
576-
WorkspaceEventsHandler handler = new WorkspaceEventsHandler(pm, client, this.documentLifeCycleHandler);
577-
handler.didChangeWatchedFiles(params);
578+
this.workspaceEventHandler.didChangeWatchedFiles(params);
578579
}
579580

580581
/* (non-Javadoc)

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/WorkspaceEventsHandler.java

+62-37
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
package org.eclipse.jdt.ls.core.internal.handlers;
1414

1515
import java.util.Collections;
16-
import java.util.List;
17-
import java.util.stream.Collectors;
16+
import java.util.concurrent.LinkedBlockingQueue;
1817

1918
import org.eclipse.core.resources.IResource;
2019
import org.eclipse.core.resources.IWorkspaceRunnable;
@@ -49,11 +48,23 @@ public class WorkspaceEventsHandler {
4948
private final ProjectsManager pm;
5049
private final JavaClientConnection connection;
5150
private final BaseDocumentLifeCycleHandler handler;
51+
private final LinkedBlockingQueue<FileEvent> queue = new LinkedBlockingQueue<>();
5252

5353
public WorkspaceEventsHandler(ProjectsManager projects, JavaClientConnection connection, BaseDocumentLifeCycleHandler handler) {
5454
this.pm = projects;
5555
this.connection = connection;
5656
this.handler = handler;
57+
Thread eventThread = new Thread(() -> {
58+
while(true) {
59+
try {
60+
FileEvent event = queue.take();
61+
handleFileEvent(event);
62+
} catch (InterruptedException e) {
63+
break;
64+
}
65+
}
66+
}, "WorkspaceEventsHandler");
67+
eventThread.start();
5768
}
5869

5970
private CHANGE_TYPE toChangeType(FileChangeType vtype) {
@@ -70,50 +81,64 @@ private CHANGE_TYPE toChangeType(FileChangeType vtype) {
7081
}
7182

7283
public void didChangeWatchedFiles(DidChangeWatchedFilesParams param) {
73-
List<FileEvent> changes = param.getChanges().stream().distinct().collect(Collectors.toList());
74-
for (FileEvent fileEvent : changes) {
75-
CHANGE_TYPE changeType = toChangeType(fileEvent.getType());
76-
if (changeType == CHANGE_TYPE.DELETED) {
77-
cleanUpDiagnostics(fileEvent.getUri());
78-
handler.didClose(new DidCloseTextDocumentParams(new TextDocumentIdentifier(fileEvent.getUri())));
79-
discardWorkingCopies(fileEvent.getUri());
84+
param.getChanges().stream().distinct().forEach(event -> {
85+
try {
86+
queue.put(event);
87+
} catch (InterruptedException e) {
88+
// do nothing
89+
}
90+
});
91+
}
92+
93+
// for test only
94+
public void handleFileEvents(FileEvent... fileEvents) {
95+
for (FileEvent fileEvent : fileEvents) {
96+
handleFileEvent(fileEvent);
97+
}
98+
}
99+
100+
private void handleFileEvent(FileEvent fileEvent) {
101+
CHANGE_TYPE changeType = toChangeType(fileEvent.getType());
102+
if (changeType == CHANGE_TYPE.DELETED) {
103+
cleanUpDiagnostics(fileEvent.getUri());
104+
handler.didClose(new DidCloseTextDocumentParams(new TextDocumentIdentifier(fileEvent.getUri())));
105+
discardWorkingCopies(fileEvent.getUri());
106+
}
107+
ICompilationUnit unit = JDTUtils.resolveCompilationUnit(fileEvent.getUri());
108+
if (unit != null && changeType == CHANGE_TYPE.CREATED && !unit.exists()) {
109+
final ICompilationUnit[] units = new ICompilationUnit[1];
110+
units[0] = unit;
111+
try {
112+
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
113+
@Override
114+
public void run(IProgressMonitor monitor) throws CoreException {
115+
units[0] = createCompilationUnit(units[0]);
116+
}
117+
}, new NullProgressMonitor());
118+
} catch (CoreException e) {
119+
JavaLanguageServerPlugin.logException(e.getMessage(), e);
80120
}
81-
ICompilationUnit unit = JDTUtils.resolveCompilationUnit(fileEvent.getUri());
82-
if (unit != null && changeType == CHANGE_TYPE.CREATED && !unit.exists()) {
83-
final ICompilationUnit[] units = new ICompilationUnit[1];
84-
units[0] = unit;
121+
unit = units[0];
122+
}
123+
if (unit != null) {
124+
if (unit.isWorkingCopy()) {
85125
try {
86-
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
87-
@Override
88-
public void run(IProgressMonitor monitor) throws CoreException {
89-
units[0] = createCompilationUnit(units[0]);
90-
}
91-
}, new NullProgressMonitor());
126+
IResource resource = unit.getUnderlyingResource();
127+
if (resource != null && resource.exists()) {
128+
resource.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
129+
}
92130
} catch (CoreException e) {
93131
JavaLanguageServerPlugin.logException(e.getMessage(), e);
94132
}
95-
unit = units[0];
133+
return;
96134
}
97-
if (unit != null) {
98-
if (unit.isWorkingCopy()) {
99-
try {
100-
IResource resource = unit.getUnderlyingResource();
101-
if (resource != null && resource.exists()) {
102-
resource.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor());
103-
}
104-
} catch (CoreException e) {
105-
JavaLanguageServerPlugin.logException(e.getMessage(), e);
106-
}
107-
continue;
108-
}
109-
if (changeType == CHANGE_TYPE.DELETED || changeType == CHANGE_TYPE.CHANGED) {
110-
if (unit.equals(CoreASTProvider.getInstance().getActiveJavaElement())) {
111-
CoreASTProvider.getInstance().disposeAST();
112-
}
135+
if (changeType == CHANGE_TYPE.DELETED || changeType == CHANGE_TYPE.CHANGED) {
136+
if (unit.equals(CoreASTProvider.getInstance().getActiveJavaElement())) {
137+
CoreASTProvider.getInstance().disposeAST();
113138
}
114139
}
115-
pm.fileChanged(fileEvent.getUri(), changeType);
116140
}
141+
pm.fileChanged(fileEvent.getUri(), changeType);
117142
}
118143

119144
private ICompilationUnit createCompilationUnit(ICompilationUnit unit) {

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/syntaxserver/SyntaxLanguageServer.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ public class SyntaxLanguageServer extends BaseJDTLanguageServer implements Langu
104104
public static final String JAVA_LSP_JOIN_ON_COMPLETION = "java.lsp.joinOnCompletion";
105105

106106
private SyntaxDocumentLifeCycleHandler documentLifeCycleHandler;
107+
private WorkspaceEventsHandler workspaceEventHandler;
107108
private ContentProviderManager contentProviderManager;
108109
private ProjectsManager projectsManager;
109110
private PreferenceManager preferenceManager;
@@ -261,6 +262,7 @@ public void initialized() {
261262
public void connectClient(JavaLanguageClient client) {
262263
super.connectClient(client);
263264
this.documentLifeCycleHandler.setClient(this.client);
265+
this.workspaceEventHandler = new WorkspaceEventsHandler(this.projectsManager, this.client, this.documentLifeCycleHandler);
264266
}
265267

266268
@Override
@@ -279,8 +281,7 @@ public void didChangeConfiguration(DidChangeConfigurationParams params) {
279281
@Override
280282
public void didChangeWatchedFiles(DidChangeWatchedFilesParams params) {
281283
logInfo(">> workspace/didChangeWatchedFiles ");
282-
WorkspaceEventsHandler handler = new WorkspaceEventsHandler(this.projectsManager, this.client, this.documentLifeCycleHandler);
283-
handler.didChangeWatchedFiles(params);
284+
this.workspaceEventHandler.didChangeWatchedFiles(params);
284285
}
285286

286287
@Override

org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/WorkspaceEventHandlerTest.java

+4-9
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,7 @@ public void testChangeWorkingCopy() throws Exception {
9696
File javaFile = new File(projectFile, "src/org/sample/Foo.java");
9797
FileUtils.writeStringToFile(javaFile, source);
9898
String uri = JDTUtils.toURI(unit);
99-
DidChangeWatchedFilesParams params = new DidChangeWatchedFilesParams(Arrays.asList(new FileEvent(uri, FileChangeType.Changed)));
100-
new WorkspaceEventsHandler(projectsManager, javaClient, lifeCycleHandler).didChangeWatchedFiles(params);
99+
new WorkspaceEventsHandler(projectsManager, javaClient, lifeCycleHandler).handleFileEvents(new FileEvent(uri, FileChangeType.Changed));
101100
waitForBackgroundJobs();
102101
assertTrue(classFile.lastModified() > lastModified);
103102
}
@@ -124,12 +123,11 @@ public void testDiscardStaleWorkingCopies() throws Exception {
124123
File newPack = new File(oldPack.getParent(), "mynewpack");
125124
Files.move(oldPack, newPack);
126125
assertTrue(unit.isWorkingCopy());
127-
DidChangeWatchedFilesParams params = new DidChangeWatchedFilesParams(Arrays.asList(
126+
new WorkspaceEventsHandler(projectsManager, javaClient, lifeCycleHandler).handleFileEvents(
128127
new FileEvent(newUri, FileChangeType.Created),
129128
new FileEvent(parentUri, FileChangeType.Changed),
130129
new FileEvent(oldUri, FileChangeType.Deleted)
131-
));
132-
new WorkspaceEventsHandler(projectsManager, javaClient, lifeCycleHandler).didChangeWatchedFiles(params);
130+
);
133131
assertFalse(unit.isWorkingCopy());
134132
}
135133

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

147145
clientRequests.clear();
148-
DidChangeWatchedFilesParams params = new DidChangeWatchedFilesParams(Arrays.asList(
149-
new FileEvent(projectUri, FileChangeType.Deleted)
150-
));
151-
new WorkspaceEventsHandler(projectsManager, javaClient, lifeCycleHandler).didChangeWatchedFiles(params);
146+
new WorkspaceEventsHandler(projectsManager, javaClient, lifeCycleHandler).handleFileEvents(new FileEvent(projectUri, FileChangeType.Deleted));
152147
waitForBackgroundJobs();
153148
assertFalse(module2.exists());
154149

0 commit comments

Comments
 (0)