readwiseio / obsidian-readwise

Official Readwise plugin for Obsidian
GNU General Public License v3.0
243 stars 23 forks source link

refactor: improve sync reliability #67

Open tyler-dot-earth opened 3 days ago

tyler-dot-earth commented 3 days ago

sync changes

Primarily:

  1. Make refreshBookExport async
    • There is no reason for it not to be, though that's largely because it is now debounced. (keep reading)
  2. Remove debounce from refreshBookExport
    • I suspect this only ever existed because the 'delete' listener fires for each file that is deleted, which in turn was firing the refreshBookExport function a ton of times. (it isn't called in the 'delete' listener anymore - keep reading)
  3. Defer refreshBookExport to sync events
    • aka don't call this when deleting files
    • ensure refreshBookExport called when syncing - both on scheduled and on-demand
  4. Generally ensure all syncing happens via refreshBookExport
    • ensures that the various sync methods won't get tangled up very easily (eg writing to settings via various sync operations in tandem)

All of these combined should ensure a much more reliably sync operation.

Extensive testing instructions found at bottom of this post ⤵

notes dump

clean plugin install happens

default data.json (aka settings):

{
  "token": "",
  "readwiseDir": "Readwise",
  "frequency": "0",
  "triggerOnLoad": true,
  "isSyncing": false,
  "lastSyncFailed": false,
  "lastSavedStatusID": 0,
  "currentSyncStatusID": 0,
  "refreshBooks": false,
  "booksToRefresh": [],
  "booksIDsMap": {},
  "reimportShowConfirmation": true
}

user clicks "connect"

note that sync frequency is manual/0 at this point

user initiates initial/first sync — this can happen one of several ways:

  1. click "initiate sync"
    • refreshBookExport
  2. Sync your data now command
    • refreshBookExport
  3. toggle on "resync deleted files"
    • refreshBookExport
  4. reload workspace
    • onloadrefreshBookExport
  5. interval is triggered
    • configureSchedulerefreshBookExport

after the initial sync, settings.lastSavedStatusID and settings.booksIDsMap are populated

at this point, the user may also use the Delete and reimport this document command within a specific Readwise export — that also simply uses refreshBookExport

notes about refreshBookExport

notes about "resync deleted files" (aka settings.refreshBooks):

other notes:

install for testing

you can download and build the plugin yourself, or use BRAT to install a pre-built beta:

  1. disable the current Readwise plugin in your Obsidian
  2. install BRAT via Obsidian community plugins and enable the BRAT plugin
  3. within BRAT's plugin settings, click the "Add Beta plugin with frozen version" button
  4. fill the fields in with the beta info Repository: https://github.com/tyler-dot-earth/dev-obsidian-readwise Latest pre-built version: refactor-improve-sync-reliability-beta-1 Should look a bit like this: Screenshot from 2024-07-06 10-48-27
  5. use the plugin like normal

how to test thoroughly

:warning: perform these in listed order

other changes

TristanH commented 3 days ago

Remove debounce from refreshBookExport I suspect this only ever existed because the 'delete' listener fires for each file that is deleted, which in turn was firing the refreshBookExport function a ton of times. (it isn't called in the 'delete' listener anymore - keep reading)

I'd definitely like us to confirm this... @tadeoos do you recollect the original rationale?

tyler-dot-earth commented 3 days ago

@TristanH

Remove debounce from refreshBookExport I suspect this only ever existed because the 'delete' listener fires for each file that is deleted, which in turn was firing the refreshBookExport function a ton of times. (it isn't called in the 'delete' listener anymore - keep reading)

I'd definitely like us to confirm this... @tadeoos do you recollect the original rationale?

Please do! I could only guess based on the code and behavior.

Given the debounce was 800ms, I can't imagine it was to compensate for some backend behavior (eg a slow sync process that would get confused by "outdated" refreshBookExport request)

The relevant changes call refreshBookExport significantly less as it is simply no longer called immediately upon deletion of every single file, instead deferring to the normal sync schedule or manual re-sync.

So beyond spamming the request, which this PR significantly reduces, i suppose the question to answer is: is there any point in keeping the debounce?

That said, I can also say:

tyler-dot-earth commented 2 days ago

@TristanH alright, i tested the heck out of this today — behavior seems solid, and I think I fixed a few more related bugs along the way.

added a ton of notes to the original post, and a big list of steps for testing.

enjoy!

tyler-dot-earth commented 1 day ago

added an install for testing section to OP with instructions on testing via BRAT instead of having to manually clone & install.

tyler-dot-earth commented 1 day ago

Noticing that null is being added to books to refresh.

Not necessarily a problem - this happened before, too - but will see if there's something specific causing it. Would be easy to filter them out, but would be better if it didn't happen to begin with.

image