Why is my Sync button blue?

I don’t think I’m capable of fixing this myself, so I’m sharing my findings here. If you can’t look into it yourself at the moment, maybe you’ll want to post it on GitHub.


First of all, even when the sync button isn't blue, syncing may still not work properly. That is, regardless of how often you press Y, Anki will never reach a synchronised state and keep modifying the db on every call. I think I've found the reason why this is happening:

Premise: A sync is performed. Now, the local and the remote collection have identical modified timestamps. We prompt another sync.
What should happen: Anki compares the two timestamps and finds that no sync is required.
What happens instead: The frontend runs self.db.execute("update col set mod=?", val) (triggered by collection.save) where val is a fresh timestamp. When the backend compares the local and remote modified timestamps now, the local one is more recent, so a sync is performed.

This happens most of the time, but not always and I can’t provide a reliable way to reproduce it. I’m also not sure why it only sometimes causes the sync button to be blue.

1 Like

Thanks for digging into it. If you run Anki with ‘TRACESQL=1 ./run’, every sql statement will be printed out, and that should help identify what sql statement is being run that is marking the database as modified (and thus causing the modtime to update on save)

After further digging, I’m now certain that this bug is out of my reach (see below). So the following is my last report on it. But if there is anything else I can help with, let me know.


During syncing, we get a timestamp from the server:

[rslib/src\sync\mod.rs:1060] new_server_mtime = TimestampMillis(1607881547128,)

However, when I print a locally generated timestamp immediately afterwards, I get

1607881544900

So the timestamp provided by the server is from the future. :upside_down_face:
This is a problem as can be demonstrated with some more printing during the next sync. There, we compare two timestamps:

db.last_begin_at: 1607881544914; mod: 1607881547128

Here, Anki gets the idea that the last local modification is more recent than the last db begin (start of database transaction):

db.mod: False; modified_after_begin: True

This triggers a db saving which in turn requires a sync.

What would have happened if the timestamp from the server had been smaller than the local timestamp as had been expected?
The mod timestamp (which is the server timestamp) would have been smaller than the begin timestamp, rendering modified_after_begin to False. Thus, no save, no sync.
Therefore, I’ve come to the conclusion that the cause of the never ending sync loop is on the server side.

1 Like

Sorry to lead you down a rabbit hole - thanks for all the research, and I’ve made a note to dig into this further.

1 Like

Does beta3 fix it for you?

As for the sync loop bug, I couldn’t reproduce it yet, but that doesn’t mean much. It appeared on some days, but not on others, seemingly independently of my actions. I’ll keep an eye on it and report back once it reoccurs or I am confident that it won’t.

Unfortunately, I had no trouble reproducing the other (?) bug, where the sync button is blue after the first sync upon start. It might be comeplety unrelated to the first one. I didn’t actually ascertain that it has the same cause.

I think that’s a separate issue - please let me know how you go with the latest master.

So on which one are you working?
Either way, what I wrote last also applies to the latest master.

I wasn’t able to reproduce the former with a clock set 30 seconds behind after applying possible fix for sync button colour blue after sync · ankitects/anki@73679b0 · GitHub, and couldn’t reproduce the latter after applying fix sync indicator turning blue after startup sync · ankitects/anki@b484516 · GitHub. What steps are you taking that triggers a problem still?

Really just syncing a change on my Android device and then launching Anki desktop. Then I still need a second sync.

I’ve just tried again while switching between versions and couldn’t reproduce the bug with the latest master whereas it appeared every time with the latest beta.
So either it’s better but not entirely fixed or you’ve fixed it completely and I have messed up earlier in which case I am sorry for the confusion.
I’ll keep an eye out, but in any case thanks for the patches!


Edit: Unfortunately, it's definitely the former case. The bug popped up again. I'll look into it.

That’s a shame. Configuration is not properly synced - #2 by Zuii is a report about add-ons marking the collection as changed, which could cause this - if you use any, it might be worth ruling them out?

I don’t have any add-ons enabled.
After db begin is set during the initial sync, there seem to be two database calls which are responsible for updating the mod stamp again:

sql: insert   or replace into config (key, usn, mtime_secs, val) values   ('activeDecks', -1, 1608712221, x'5b313535393539303330363434385d')
sql: insert   or replace into config (key, usn, mtime_secs, val) values   ('curDeck', -1, 1608712221, x'31353539353930333036343438')

I don’t know if that tells you anything. Of course, you can’t do much if you can’t reproduce the issue on your machine.
I’ll see what I can find out after the holidays.

col.decks.select() is called by .reset() after the sync finishes. If the deck to select and its children haven’t changed then it should be a no-op. Might be worth checking the if statement in that function and seeing what’s not matching - maybe activeDecks needs to be sorted before comparing?

1 Like