diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/AnalyzeProjectOnStart.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/AnalyzeProjectOnStart.java index 94ef6e95b14..5283444a4f6 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/AnalyzeProjectOnStart.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/AnalyzeProjectOnStart.java @@ -25,6 +25,7 @@ import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; import com.github._1c_syntax.bsl.languageserver.context.events.ServerContextPopulatedEvent; import com.github._1c_syntax.bsl.languageserver.providers.DiagnosticProvider; +import com.github._1c_syntax.bsl.languageserver.utils.NamedForkJoinWorkerThreadFactory; import com.github._1c_syntax.bsl.languageserver.utils.Resources; import lombok.RequiredArgsConstructor; import org.springframework.context.event.EventListener; @@ -63,7 +64,8 @@ public void handleEvent(ServerContextPopulatedEvent event) { var progress = workDoneProgressHelper.createProgress(documentContexts.size(), getMessage("filesSuffix")); progress.beginProgress(getMessage("analyzeProject")); - var executorService = new ForkJoinPool(ForkJoinPool.getCommonPoolParallelism()); + var factory = new NamedForkJoinWorkerThreadFactory("analyze-on-start-"); + var executorService = new ForkJoinPool(ForkJoinPool.getCommonPoolParallelism(), factory, null, true); try { executorService.submit(() -> diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLLanguageServer.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLLanguageServer.java index 12553fed938..19ba3a0b523 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLLanguageServer.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLLanguageServer.java @@ -28,6 +28,7 @@ import com.github._1c_syntax.bsl.languageserver.jsonrpc.ProtocolExtension; import com.github._1c_syntax.bsl.languageserver.providers.CommandProvider; import com.github._1c_syntax.bsl.languageserver.providers.DocumentSymbolProvider; +import com.github._1c_syntax.bsl.languageserver.utils.NamedForkJoinWorkerThreadFactory; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.lsp4j.CallHierarchyRegistrationOptions; @@ -62,7 +63,6 @@ import org.eclipse.lsp4j.services.LanguageServer; import org.eclipse.lsp4j.services.TextDocumentService; import org.eclipse.lsp4j.services.WorkspaceService; -import org.springframework.scheduling.concurrent.CustomizableThreadFactory; import org.springframework.stereotype.Component; import java.io.File; @@ -73,8 +73,7 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.util.concurrent.ForkJoinPool; @Slf4j @Component @@ -97,8 +96,13 @@ public CompletableFuture initialize(InitializeParams params) { clientCapabilitiesHolder.setCapabilities(params.getCapabilities()); setConfigurationRoot(params); - ExecutorService executorService = Executors.newCachedThreadPool(new CustomizableThreadFactory("populate-context-")); - CompletableFuture.runAsync(context::populateContext, executorService); + + var factory = new NamedForkJoinWorkerThreadFactory("populate-context-"); + var executorService = new ForkJoinPool(ForkJoinPool.getCommonPoolParallelism(), factory, null, true); + CompletableFuture + .runAsync(context::populateContext, executorService) + .thenAccept(unused -> executorService.shutdown()) + ; var capabilities = new ServerCapabilities(); capabilities.setTextDocumentSync(getTextDocumentSyncOptions()); diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java index ff5cf9b9135..6dbca3ef889 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java @@ -44,6 +44,7 @@ import com.github._1c_syntax.bsl.languageserver.providers.RenameProvider; import com.github._1c_syntax.bsl.languageserver.providers.SelectionRangeProvider; import com.github._1c_syntax.bsl.languageserver.utils.Ranges; +import jakarta.annotation.PreDestroy; import lombok.RequiredArgsConstructor; import org.eclipse.lsp4j.CallHierarchyIncomingCall; import org.eclipse.lsp4j.CallHierarchyIncomingCallsParams; @@ -127,6 +128,11 @@ public class BSLTextDocumentService implements TextDocumentService, ProtocolExte private final ExecutorService executorService = Executors.newCachedThreadPool(new CustomizableThreadFactory("text-document-service-")); + @PreDestroy + private void onDestroy() { + executorService.shutdown(); + } + @Override public CompletableFuture hover(HoverParams params) { var documentContext = context.getDocument(params.getTextDocument().getUri()); @@ -278,7 +284,8 @@ public CompletableFuture> prepareCallHierarchy(CallHiera } return callHierarchyItems; }, - executorService); + executorService + ); } @Override diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLWorkspaceService.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLWorkspaceService.java index 4d0cba21357..2ed324237aa 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLWorkspaceService.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLWorkspaceService.java @@ -24,6 +24,7 @@ import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; import com.github._1c_syntax.bsl.languageserver.providers.CommandProvider; import com.github._1c_syntax.bsl.languageserver.providers.SymbolProvider; +import jakarta.annotation.PreDestroy; import lombok.RequiredArgsConstructor; import org.apache.commons.beanutils.PropertyUtils; import org.eclipse.lsp4j.DidChangeConfigurationParams; @@ -53,6 +54,11 @@ public class BSLWorkspaceService implements WorkspaceService { private final ExecutorService executorService = Executors.newCachedThreadPool(new CustomizableThreadFactory("workspace-service-")); + @PreDestroy + private void onDestroy() { + executorService.shutdown(); + } + @Override public CompletableFuture,List>> symbol(WorkspaceSymbolParams params) { return CompletableFuture.supplyAsync( diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContext.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContext.java index c8a9b7067f2..67e54a57078 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContext.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContext.java @@ -24,6 +24,7 @@ import com.github._1c_syntax.bsl.languageserver.WorkDoneProgressHelper; import com.github._1c_syntax.bsl.languageserver.configuration.LanguageServerConfiguration; import com.github._1c_syntax.bsl.languageserver.utils.MdoRefBuilder; +import com.github._1c_syntax.bsl.languageserver.utils.NamedForkJoinWorkerThreadFactory; import com.github._1c_syntax.bsl.languageserver.utils.Resources; import com.github._1c_syntax.bsl.types.ModuleType; import com.github._1c_syntax.mdclasses.Configuration; @@ -280,8 +281,10 @@ private Configuration computeConfigurationMetadata() { var progress = workDoneProgressHelper.createProgress(0, ""); progress.beginProgress(getMessage("computeConfigurationMetadata")); + var factory = new NamedForkJoinWorkerThreadFactory("compute-configuration-"); + var executorService = new ForkJoinPool(ForkJoinPool.getCommonPoolParallelism(), factory, null, true); + Configuration configuration; - var executorService = new ForkJoinPool(ForkJoinPool.getCommonPoolParallelism()); try { configuration = executorService.submit(() -> Configuration.create(configurationRoot)).get(); } catch (ExecutionException e) { diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/DiagnosticComputer.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/DiagnosticComputer.java index 6a91c3d43ab..b2de3ea0022 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/DiagnosticComputer.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/context/computer/DiagnosticComputer.java @@ -23,23 +23,45 @@ import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; import com.github._1c_syntax.bsl.languageserver.diagnostics.BSLDiagnostic; -import lombok.RequiredArgsConstructor; +import com.github._1c_syntax.bsl.languageserver.utils.NamedForkJoinWorkerThreadFactory; +import jakarta.annotation.PostConstruct; +import jakarta.annotation.PreDestroy; import lombok.extern.slf4j.Slf4j; import org.eclipse.lsp4j.Diagnostic; import org.springframework.beans.factory.annotation.Lookup; import org.springframework.stereotype.Component; import java.util.List; -import java.util.stream.Collectors; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ForkJoinPool; +import java.util.function.Predicate; import java.util.stream.Stream; @Component -@RequiredArgsConstructor @Slf4j public abstract class DiagnosticComputer { + private ExecutorService executorService; + + @PostConstruct + private void init() { + var factory = new NamedForkJoinWorkerThreadFactory("diagnostic-computer-"); + executorService = new ForkJoinPool(ForkJoinPool.getCommonPoolParallelism(), factory, null, true); + } + + @PreDestroy + private void onDestroy() { + executorService.shutdown(); + } + public List compute(DocumentContext documentContext) { + return CompletableFuture + .supplyAsync(() -> internalCompute(documentContext), executorService) + .join(); + } + private List internalCompute(DocumentContext documentContext) { DiagnosticIgnoranceComputer.Data diagnosticIgnorance = documentContext.getDiagnosticIgnorance(); return diagnostics(documentContext).parallelStream() @@ -64,9 +86,8 @@ public List compute(DocumentContext documentContext) { return Stream.empty(); } }) - .filter((Diagnostic diagnostic) -> - !diagnosticIgnorance.diagnosticShouldBeIgnored(diagnostic)) - .collect(Collectors.toList()); + .filter(Predicate.not(diagnosticIgnorance::diagnosticShouldBeIgnored)) + .toList(); } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/NamedForkJoinWorkerThreadFactory.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/NamedForkJoinWorkerThreadFactory.java new file mode 100644 index 00000000000..59a4ceaa2c1 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/NamedForkJoinWorkerThreadFactory.java @@ -0,0 +1,31 @@ +package com.github._1c_syntax.bsl.languageserver.utils; + +import lombok.RequiredArgsConstructor; + +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinWorkerThread; +import java.util.concurrent.atomic.AtomicLong; + +/** + * Фабрика тредов для ForkJoinPool, автоматически добаляющая префикс к имени треда. + */ +@RequiredArgsConstructor +public class NamedForkJoinWorkerThreadFactory implements ForkJoinPool.ForkJoinWorkerThreadFactory { + + private static final AtomicLong index = new AtomicLong(); + + /** + * Префикс для добавления к имени треда. + */ + private final String prefix; + + /** + * {@inheritDoc} + */ + @Override + public ForkJoinWorkerThread newThread(ForkJoinPool pool) { + var worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool); + worker.setName(prefix + index.incrementAndGet()); + return worker; + } +}