mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
do not try to commit all documents synchronously if there are too many of them in the queue, it will freeze EDT (part of IJPL-50077 freezing on replace)
GitOrigin-RevId: 2a10e2f817fa46ab0854cddc7cff9dd676695b3a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
6eb4c859ff
commit
26e13c9315
@@ -78,8 +78,6 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
|
||||
private final Map<Document, Throwable> myUncommittedDocumentTraces = CollectionFactory.createConcurrentWeakMap();
|
||||
private /*non-static*/ final Key<UncommittedInfo> UNCOMMITTED_INFO_KEY = Key.create("UNCOMMITTED_INFO");
|
||||
|
||||
@ApiStatus.Internal
|
||||
protected boolean myStopTrackingDocuments;
|
||||
private boolean myPerformBackgroundCommit = true;
|
||||
|
||||
@SuppressWarnings("ThreadLocalNotStaticFinal")
|
||||
@@ -983,7 +981,9 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
|
||||
|
||||
@Override
|
||||
public void beforeDocumentChange(@NotNull DocumentEvent event) {
|
||||
if (myStopTrackingDocuments || myProject.isDisposed()) return;
|
||||
if (myProject.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Document document = event.getDocument();
|
||||
VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(document);
|
||||
@@ -1026,7 +1026,7 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
|
||||
|
||||
@Override
|
||||
public void documentChanged(@NotNull DocumentEvent event) {
|
||||
if (myStopTrackingDocuments || myProject.isDisposed()) {
|
||||
if (myProject.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1088,32 +1088,27 @@ public abstract class PsiDocumentManagerBase extends PsiDocumentManager implemen
|
||||
}
|
||||
|
||||
// optimisation: avoid documents piling up during batch processing
|
||||
if (isUncommited(document) && areTooManyDocumentsInTheQueue(myUncommittedDocuments)) {
|
||||
// must not commit during document save
|
||||
if (PomModelImpl.isAllowPsiModification()
|
||||
// it can happen that document(forUseInNonAWTThread=true) outside write action caused this
|
||||
&& ApplicationManager.getApplication().isWriteAccessAllowed()) {
|
||||
// commit one document to avoid OOME
|
||||
for (Document uncommitted : myUncommittedDocuments) {
|
||||
if (uncommitted != event.getDocument()) {
|
||||
commitDocument(uncommitted);
|
||||
break;
|
||||
if (myUnitTestMode && isUncommited(document) && areTooManyDocumentsInTheQueue(myUncommittedDocuments)) {
|
||||
try {
|
||||
Logger.getInstance(getClass()).error(
|
||||
"Too many uncommitted documents (" +myUncommittedDocuments.size()+"):\n"
|
||||
+ StringUtil.join(myUncommittedDocuments, "\n") + myProject);
|
||||
// must not commit during document save
|
||||
if (PomModelImpl.isAllowPsiModification()
|
||||
// it can happen that document(forUseInNonAWTThread=true) outside write action caused this
|
||||
&& ApplicationManager.getApplication().isWriteAccessAllowed()) {
|
||||
// commit one document to avoid OOME
|
||||
for (Document uncommitted : myUncommittedDocuments) {
|
||||
if (uncommitted != document) {
|
||||
commitDocument(uncommitted);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (myUnitTestMode) {
|
||||
myStopTrackingDocuments = true;
|
||||
try {
|
||||
//noinspection TestOnlyProblems
|
||||
Logger.getInstance(getClass()).error(
|
||||
"Too many uncommitted documents for " + myProject + "(" +myUncommittedDocuments.size()+")"+
|
||||
":\n" + StringUtil.join(myUncommittedDocuments, "\n") +
|
||||
myProject);
|
||||
}
|
||||
finally {
|
||||
//noinspection TestOnlyProblems
|
||||
clearUncommittedDocuments();
|
||||
}
|
||||
finally {
|
||||
//noinspection TestOnlyProblems
|
||||
clearUncommittedDocuments();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+33
-4
@@ -41,10 +41,7 @@ import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
|
||||
import com.intellij.openapi.vfs.limits.FileSizeLimit;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.PsiFileImpl;
|
||||
import com.intellij.testFramework.HeavyPlatformTestCase;
|
||||
import com.intellij.testFramework.LeakHunter;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import com.intellij.testFramework.PlatformTestUtil;
|
||||
import com.intellij.testFramework.*;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.TestTimeOut;
|
||||
@@ -66,6 +63,7 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
@@ -994,4 +992,35 @@ public class PsiDocumentManagerImplTest extends HeavyPlatformTestCase {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testHugeAmountOfChangedDocumentsMustNotCauseSynchronousCommitLeadingToUIFreeze() {
|
||||
LoggedErrorProcessor.executeWith(new LoggedErrorProcessor() {
|
||||
@Override
|
||||
public @NotNull Set<Action> processError(@NotNull String category, @NotNull String message, String @NotNull [] details, Throwable t) {
|
||||
if (message.contains("Too many uncommitted documents")) {
|
||||
return Action.NONE;
|
||||
}
|
||||
return super.processError(category, message, details, t);
|
||||
}
|
||||
}, () -> {
|
||||
PsiDocumentManagerImpl psiDocumentManager = (PsiDocumentManagerImpl)PsiDocumentManager.getInstance(getProject());
|
||||
psiDocumentManager.myUnitTestMode = false; // test the prod behaviour
|
||||
try {
|
||||
for (int i=0;i<5_000;i++) {
|
||||
PsiFile mainFile = findFile(createFile());
|
||||
Document doc = getDocument(mainFile);
|
||||
psiDocumentManager.addRunOnCommit(doc, d ->{
|
||||
ApplicationManager.getApplication().assertIsNonDispatchThread();
|
||||
});
|
||||
WriteCommandAction.runWriteCommandAction(getProject(), () -> {
|
||||
doc.insertString(0," ");
|
||||
});
|
||||
}
|
||||
}
|
||||
finally {
|
||||
psiDocumentManager.myUnitTestMode = true;
|
||||
psiDocumentManager.clearUncommittedDocuments();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user