tsudoko/anki-sync-server

Checking database while having freshly added cards in a deck causes inconsistency

kuklinistvan opened this issue · 4 comments

Hey tsudoku,

I am not sure if I should this report to you or directly to the developers of Anki Desktop, but I have encountered an interesting behavior that can break syncing, while I was about to update the image to support the latest version of Anki.

Anki Desktop version: 2.1.14
ankisyncd version: 7ef3d4f on master

Reproduction:

  1. Set up ankisyncd and point an Anki Desktop instance to it

  2. Create a deck and some cards, maybe manipulate them

  3. Synchronize making sure it works at this point

  4. Ensure that you have at least one completely fresh, unreviewed card
    It should look as follows in the browser:
    due1000000

  5. Synchronize again - it should still work

  6. BREAK IT: Hit Check datatabase...

A message similar to this one should appear:
Found 1 new cards with a due number >= 1,000,000 - consider repositioning them in the Browse screen.
Database rebuilt and optimized.

  1. Sync again - now it is broken
    inconsistent

The server output does not seem to contain too much useful information at the very moment this message appears on the client side:

[2019-07-08 12:31:20,928]:INFO:ankisyncd.CollectionThread[sajat_anki]:Running meta(*[], **{'v': 9, 'cv': 'ankidesktop,2.1.14 (7b93e985),lin:arch:rolling'})
[2019-07-08 12:31:20,930]:INFO:ankisyncd.http:172.17.0.1 "POST /sync/meta HTTP/1.1" 200 112

What do you think, is it related to ankisyncd or should I forward this bug to the developers of Anki Desktop?

Best regards,
István

Are you still able to reproduce this? Does the due number change to 100000 right after syncing or is the change caused by something else than sync?

The >=1000000 behavior you're seeing seems to be intentional, so as long as the due number isn't changed by ankisyncd during sync, this is not an ankisyncd issue.
https://github.com/ankitects/anki/blob/7b93e9855ef378b1ab75c479d9e47f57f2bb4689/anki/collection.py#L851-L857

        # new cards can't have a due position > 32 bits, so wrap items over
        # 2 million back to 1 million
        curs.execute("""
update cards set due=1000000+due%1000000,mod=?,usn=? where due>=1000000
and type=0""", [intTime(), self.usn()])
        if curs.rowcount:
            problems.append("Found %d new cards with a due number >= 1,000,000 - consider repositioning them in the Browse screen." % curs.rowcount)

https://github.com/ankitects/anki/blob/7b93e9855ef378b1ab75c479d9e47f57f2bb4689/anki/collection.py#L884-L888

        ok = not problems
        problems.append(txt)
        # if any problems were found, force a full sync
        if not ok:
            self.modSchema(check=False)

Due wrapping seems to have been introduced in 2.1.13 in ankitects/anki@599f574.

I couldn't reproduce this on either 2.1.14, 2.1.15 or 2.1.19 unless I manually repositioned the card. If it's something you can still reproduce even after repositioning your existing cards and using AnkiWeb to sync, it might be worth reporting upstream.

Thank you for investigating the root of the problem!

Good news - I've tested this behavior with Anki Desktop version 2.1.19.

Képernyőkép_2020-02-03_16-43-19

In this version a new card does not receive a due value of 1000000 but rather the next one from a sequence starting from 1, as seen in the attached picture.

The error message does not appear and the consistency is not broken.

Before closing this issue, I'm doing some manual tests to see whether ankisyncd is capable of handling version 2.1.19 already.

Oh no, I see it again.

I was synchronizing the cards back and forth and it happened again :(

AnkiDroid version 2.9.1 and Anki Desktop 2.1.19

Képernyőkép_2020-02-03_17-15-22

Did not find out how to reproduce it yet...

Well, it became harder to reproduce and mostly I am able to test it without running into this problem.

Because it now occurs only very rarely and not in a special predictable way like before, I'm releasing a new Docker image.

Thanks again for maintaining ankisyncd, it is an awesome project!