Quickadd currently performs a full read of the target file upon command activation, and prompts for user input, and finally formats the input to target file. During the wait for input stage, which typically takes several seconds for user to type something, any external updates (typically from Obsidian Sync) to that file is lost. Quickadd then overwrites the file with updated ones based on the old version.
This is a followup to a bug report to Obsidian Sync that I submitted earlier to the Obsidian Forum. In that thread, @lishid pointed out that it could be one of the plugins overwriting the file with outdated content, which made me realize every time that Sync bug happens I was always using Quickadd to write something.
Cause
Current function call stack when triggering the Quickadd capture is as follows:
constfilePath=awaitthis.getFilePath(captureTo);letcontent=awaitthis.getCaptureContent();letfile: TFile;if(awaitthis.fileExists(filePath)){file=awaitthis.getFileByPath(filePath);if(!file)return;constfileContent: string=awaitthis.app.vault.read(file);constnewFileContent: string=awaitthis.formatter.formatContentWithFile(content,this.choice,fileContent,file);// the above function waits for user input. awaitthis.app.vault.modify(file,newFileContent);}
And the this.formatter.formatContentWithFile would call into promptForValue() down the road, which creates an InputPrompt and waits for user input. Depending on how much text the user want to type, this would take several seconds to several minutes, and we definitely don't want to discard external updates to the file during this period.
A potential improvement
To avoid race condition, and minimize the possibility of simultaneous update to the same file, we'd like to minimize the duration between file reads and file writes, i.e. we'd like to make sure the update we perform is based on the latest version.
Current call sequence
read file content
format file content
prompt and wait for user input (long running)
process user input and format to file
return updated file
write updated file to vault
Suggested call sequence
prompt and wait for user input (long running)
read file content
format file content with user input
write updated file to vault
To Reproduce
The common use case to trigger this issue:
iOS and Mac has note xxx.md at version 1
Edit note (xxx.md) on Mac to make it version 2, Sync uploads the file
Open iOS Obsidian
Obsidian Sync tries to pull updates (version 2) from server
Start QuickAdd capture from command, and start to write, QuickAdd reads file at version 1
Obsidian Sync finishes the download, and updates the file xxx.md to version 2
Finishes writing, click OK on QuickAdd prompt
QuickAdd writes the formatted / updated file to vault, making it a new version (it's version 3 to Sync)
The version 3 is synced across all device, version 2 update is lost
This is 100% consistently reproducible.
Expected behavior
If the file we want to edit is no longer the latest version, it should at least trigger the obsidian's conflict resolution, and should never nuke any file updates.
Describe the bug
Quickadd currently performs a full read of the target file upon command activation, and prompts for user input, and finally formats the input to target file. During the wait for input stage, which typically takes several seconds for user to type something, any external updates (typically from Obsidian Sync) to that file is lost. Quickadd then overwrites the file with updated ones based on the old version.
This is a followup to a bug report to Obsidian Sync that I submitted earlier to the Obsidian Forum. In that thread, @lishid pointed out that it could be one of the plugins overwriting the file with outdated content, which made me realize every time that Sync bug happens I was always using Quickadd to write something.
Cause
Current function call stack when triggering the Quickadd capture is as follows:
src/engine/CaptureChoiceEngine.ts:
async run(): Promise<void>And the
this.formatter.formatContentWithFilewould call intopromptForValue()down the road, which creates anInputPromptand waits for user input. Depending on how much text the user want to type, this would take several seconds to several minutes, and we definitely don't want to discard external updates to the file during this period.A potential improvement
To avoid race condition, and minimize the possibility of simultaneous update to the same file, we'd like to minimize the duration between file reads and file writes, i.e. we'd like to make sure the update we perform is based on the latest version.
Current call sequence
Suggested call sequence
To Reproduce
The common use case to trigger this issue:
xxx.mdat version 1xxx.md) on Mac to make it version 2, Sync uploads the filexxx.mdto version 2This is 100% consistently reproducible.
Expected behavior
If the file we want to edit is no longer the latest version, it should at least trigger the obsidian's conflict resolution, and should never nuke any file updates.
Additional context
Relevant Obsidian Sync Bug Report: https://forum.obsidian.md/t/obsidian-sync-updates-from-one-device-overwritten-by-another/33007
The text was updated successfully, but these errors were encountered: