-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: improve sync reliability #67
refactor: improve sync reliability #67
Conversation
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 - (1) don't call this when deleting files - (2) ensure refreshBookExport called when syncing - both on scheduled and on-demand All of these combined should ensure a much more reliably sync operation.
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" The relevant changes call 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:
|
- Handles "Resync deleted files" case when deletin file - Fixed/adjusted various uses of refreshBookExport, startSync, and requestArchive (which were a bit muddled before)
@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! |
added an |
This comment was marked as resolved.
This comment was marked as resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome work on this man. hopefully @tadeoos can have a thorough review next week
in the mean time, we've been testing it internally and so far so good!
also really appreciate you sharing it on the reddit and making the testing process easy 😍
@TristanH i appreciate the support! and very happy to hear that you guys have been testing it internally without issue. i pushed one final change removing the i'll keep a look out for review comments 😃 |
Anything I can do to help get this merged? Its making the Obsidian integration much less usable for me. |
@homostellaris in general we are pretty game to merge this last i heard (@tyler-dot-earth correct me if i'm wrong) we didn't actually think that the changes here would solve a lot of the syncing issues linked (which are usually caused by using Obsidian Sync) but if we think they will substantially help, definitely game to merge them |
@TristanH While this PR won't resolve the "race condotion" of Readwise sync vs Obsidian Sync which is clobbering book IDs (#68), it does substantially improve the ability to resync deleted items, unify resync logic, fix issues where the plugin thought there was nothing to sync, reduces hacks/workarounds, and generally improve the codebase. I could have made those improvements more clear in my OP — my bad. I've been using it this whole time with no issue aside from the (preexisting) book IDs issue that is caused by the aforementioned race condition. I have ideas about how to improve/fix that (#68), though hesitant to start on them until these fixes/restructure is approved 🙂 |
@tyler-dot-earth great! @tadeoos should be able to do one final code review tomorrow, and then I think we'll be good to get it merged 👍 not your fault at all, i should have asked |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dude... Really nice work!
Thanks so much for the PR and thanks a ton for your patience as I was focused on some high prio stuff (completely unrelated to Obsidian) and finally got time to review this just today. Also: thanks for making my old typescript code suck less :)
I want to move responsibly here as I haven't touched this in a couple of years so I don't remember all of the nitty-gritty details right away — I left some comments to make sure I understand your intentions and pointed out some places where you may have missed some UX corner cases...
But all in all, I think we're close to shipping this, hopefully early next week!
One more thing:
I'm not sure I see this logic fully implemented in your current version... We now only add books to |
Ah, yes - I think I wrote that before I made the changes to the deletion logic which obsolesced the need for storing the deleted IDs in the |
Thank you for the review @tadeoos :) I have given an initial look-through, good feedback - I should hopefully have some time this weekend to really dig in and make updates. |
@tadeoos Did a round of fixes and responses to your review. Also bumped the BRAT version to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a ton for a quick iteration here, great changes!
This reverts commit a208165.
related issues
booksIDsMap
indata.json
#68booksIDsMap
altogether - so i suspect it should help as that is now modified lesstl;dr
sync changes
Note
some name changes since i originally posted the notes below, see this comment
refreshBookExport
has been renamed tosyncBookHighlights
startSync
has been folded intorequestArchive
requestArchive
has been renamed toqueueExport
downloadArchive
has been renamed todownloadExport
Primarily:
refreshBookExport
asyncit is now debounced. (keep reading)
debounce
from refreshBookExportfires for each file that is deleted, which in turn was firing
the
refreshBookExport
function a ton of times. (it isn't calledin the 'delete' listener anymore - keep reading)
refreshBookExport
to sync eventsrefreshBookExport
called when syncing - both onscheduled and on-demand
refreshBookExport
Additionally:
saveSettings
- i suspect this was causing issues where settings would get clobbered. either way, couldn't see a reason not to do this in most cases.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
(akasettings
):user clicks "connect"
getUserAuthToken()
→ saves tosettings.token
https://readwise.io/export/obsidian/preferences
note that sync frequency is manual/
0
at this pointuser initiates initial/first sync — this can happen one of several ways:
refreshBookExport
Sync your data now
commandrefreshBookExport
refreshBookExport
onload
→refreshBookExport
configureSchedule
→refreshBookExport
after the initial sync,
settings.lastSavedStatusID
andsettings.booksIDsMap
are populatedat this point, the user may also use the
Delete and reimport this document
command within a specific Readwise export — that also simply usesrefreshBookExport
notes about
refreshBookExport
refreshBookExport
will always trigger arequestArchive
(either directly or viastartSync
), regardless of if it was provided specific books to refresh, so new highlights should always appearnotes about "resync deleted files" (aka
settings.refreshBooks
):booksIDsMap
so we have a copy of its book IDbooksToRefresh
as they are deleted (seeif enabled
for rationale)refreshBookExport
will look for a difference in the filesystem vs what is inbooksIDsMap
— seemed like the only way to handle filesystem deletions (outside of Obsidian), unknown performance when there are many many readwise files. could be moved behind a toggle if it's particularly slow.other notes:
auto
query string seems to indicate that the sync wasn't triggered by a user (eg interval sync)settings.readwiseDir
isn't there, therequestArchive
will use theparentPageDeleted
querystring (like/api/obsidian/init?parentPageDeleted=true
) — there's no documentation on this, but i did test it and it does successfully sync the files in a clean installinstall for testing
you can download and build the plugin yourself, or use BRAT to install a pre-built beta:
Repository:
https://github.com/tyler-dot-earth/dev-obsidian-readwise
Latest pre-built version:
refactor-improve-sync-reliability-beta-5
Should look a bit like this:
how to test thoroughly
Warning
perform these in listed order
confirm clean plugin install syncs notes as expected (this isn't automatic; you must click "initiate sync" or reload the workspace after authenticating)
enable
Resync deleted files
delete a synced file
use command palette to
Readwise Official: Sync your data now
confirm deleted file is re-synced
delete a synced file
open plugin settings and click
Initiate sync
confirm deleted file is re-synced
open a synced file
use command palette to
Readwise Official: Delete and reimport this document
confirm file is deleted and is re-synced
delete synced file
use command palette to
Reload app without saving
(or re-open Obsidian)confirm deleted file is re-synced
disable
Resync deleted files
delete a synced file
use command palette to
Readwise Official: Sync your data now
confirm file is NOT re-synced
delete a synced file
open plugin settings and click
Initiate sync
confirm file is NOT re-synced
delete synced file
use command palette to
Reload app without saving
(or re-open Obsidian)confirm deleted file isn't re-synced
open a synced file
use command palette to
Readwise Official: Delete and reimport this document
confirm file is re-synced
delete synced file
enable
Resync deleted files
confirm deleted file is re-synced
and finally, for good measure:
ensure adding new highlights continues to work as expected
ensure syncing on interval continues to work as expected
other changes