Execute attachment box render sub-tasks concurrently
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run

resolve: #4611
Try to avoid race condition in dense render calls.
We used to notify the preview to update
after all other renders are done,
which can cause unexpected race condition.
This commit is contained in:
windingwind 2024-09-03 04:16:17 +00:00 committed by Dan Stillman
parent 3861af50d1
commit 1f8b480e70
2 changed files with 29 additions and 15 deletions

View file

@ -326,13 +326,12 @@
Zotero.debug('Refreshing attachment box');
this._asyncRendering = true;
await this.renderAttachmentInfo();
if (this.usePreview) {
this.previewElem.item = this.item;
await this.previewElem.render();
}
// Execute sub-tasks concurrently to avoid race condition between different calls
await Promise.all([
this.updateInfo(),
this.updatePreview()
]);
this._asyncRendering = false;
@ -358,7 +357,7 @@
ZoteroPane_Local.showAttachmentInFilesystem(this.item.id, event.originalTarget, !this.editable);
}
async renderAttachmentInfo() {
async updateInfo() {
// Cancel editing filename when refreshing
this._isEditingFilename = false;
@ -504,6 +503,13 @@
}
}
async updatePreview() {
if (this.usePreview) {
this.previewElem.item = this.item;
await this.previewElem.render();
}
}
updateItemIndexedState() {
return (async () => {
let indexStatus = this._id('index-status');

View file

@ -195,15 +195,12 @@
this._renderStage = "final";
this._asyncRendering = true;
await this._updateAttachmentIDs();
// Execute sub-tasks concurrently to avoid race condition between different calls
await Promise.all([
this.updateRows(),
this.updatePreview(),
]);
let itemAttachments = Zotero.Items.get(this._attachmentIDs);
this._attachments.querySelectorAll("attachment-row").forEach(e => e.remove());
for (let attachment of itemAttachments) {
this.addRow(attachment);
}
await this.updatePreview();
this._asyncRendering = false;
}
@ -226,6 +223,17 @@
this._section.setCount(count);
}
async updateRows() {
await this._updateAttachmentIDs();
let itemAttachments = Zotero.Items.get(this._attachmentIDs);
this._attachments.querySelectorAll("attachment-row").forEach(e => e.remove());
for (let attachment of itemAttachments) {
this.addRow(attachment);
}
}
async updatePreview() {
// Skip if asyncRender is not finished/executed, which means the box is invisible
// The box will be rendered when it becomes visible