Skip to content
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

error while sync: #8

Open
sandroden opened this issue Dec 4, 2020 · 8 comments
Open

error while sync: #8

sandroden opened this issue Dec 4, 2020 · 8 comments

Comments

@sandroden
Copy link

I managed to sync in various situation with and w/o images but I also got into a situation in which from Anki Desktop I have this error:

/djs/sync/applyGraves
POST HTTP/1.1
Content-Length: 684
Content-Type: multipart/form-data; boundary=8c0a09497de60d5e-50bd504f1c7e1b00-830495ea2a49990d-eb6af20e78b0e954
Http-X-Real-Ip: 192.168.32.1
Http-X-Forwarded-For: 192.168.32.1
Http-X-Forwarded-Proto: http
Http-Host: djankiserv.wikidattica.org
Http-Connection: close
Http-Accept: */*
Http-X-Forwarded-Host: djankiserv.wikidattica.org
Http-X-Forwarded-Port: 443
Http-X-Forwarded-Server: c862b9f3bf7f
Http-Accept-Encoding: gzip


<QueryDict: {'c': ['1'], 'k': ['njs0i8hylaltkpbufn7egtvboq22zik3'], 's': ['r`E^Bs={pI'], 'data': [<InMemoryUploadedFile: data ()>]}>


Internal Server Error: /djs/sync/applyGraves
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.8/site-packages/django/core/handlers/base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/usr/local/lib/python3.8/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/rest_framework/decorators.py", line 50, in handler
    return func(*args, **kwargs)
  File "./djankiserv/sync/views.py", line 123, in base_applyGraves
    col_handler.applyGraves(chunk=data.get("chunk"))
  File "./djankiserv/sync/__init__.py", line 53, in applyGraves
    self.remove(chunk)
  File "./djankiserv/sync/__init__.py", line 176, in remove
    self.col.decks.rem(oid, children_too=False)
  File "./djankiserv/unki/decks.py", line 220, in rem
    self.col.sched.emptyDyn(did)
AttributeError: 'Scheduler' object has no attribute 'emptyDyn'
Not Found: /djs/sync/abort

The same collection synced to a completely new user doesn't have any problem.
Is there some tests I can do to debug what's happening?

@AntonOfTheWoods
Copy link
Contributor

AntonOfTheWoods commented Dec 4, 2020

Ciao @sandroden , I know what's happening - this is a code path that doesn't have test coverage, and has a method I removed from the Scheduler class. Here you have an example of the question you asked about usage of the sched module - it uses the scheduler to delete scheduled cards data. Sigh...

I have a fix (basically just getting the original method and cleaning it up) but there are a few other things to do and I have some marking that really needs to be finished today, so can't guarantee to push before tomorrow.

If you want to test it out, add

    def emptyDyn(self, deck_id, limit=None):
        if not limit:
            limit = f"did = {deck_id}"
        self.col.log(self.col.db.list(f"select id from cards where {limit}"))
        # move out of cram queue
        self.col.db.execute(
            f"""
            update cards set did = odid, queue = (case when type = 1 then 0
            else type end), type = (case when type = 1 then 0 else type end),
            due = odue, odue = 0, odid = 0, usn = %s where {limit}""",
            self.col.usn(),
        )

To the bottom of the sched.Scheduler class.

@AntonOfTheWoods
Copy link
Contributor

@sandroden , this is included in the emptyDyn branch I just created https://github.com/ankicommunity/djankiserv/tree/emptyDyn. If you confirm it fixes your problem I will merge, and even better if you could work out a minimal repro deck I'd love to include that in the tests!

@sandroden
Copy link
Author

Thank you @AntonOfTheWoods . I hope to test it in a couple of hours. As far as creating the repro deck I have to think about how to do it as it's not a problem with the deck. The same deck synced to a different fresh user doesn't have problems. In fact, I should probably save the situation on the server, before testing. If you have any idea I'm happy to hear.

@AntonOfTheWoods
Copy link
Contributor

@sandroden , a dump of the DB would be ideal, at least of the col table in the user schema. I am almost certain it is because it was an update to an existing user that had a few operations already, rather than syncing to a new user. Is that correct? Things are very simple when you just have to push an entire DB, when you need to sync state between two divergent DBs, things get much more complicated.

@sandroden
Copy link
Author

Sorry for the delay @AntonOfTheWoods , family duties had priority...
Your patch worked with this minor fix:

diff --git a/src/djankiserv/unki/sched.py b/src/djankiserv/unki/sched.py
index 0919fd6..86cd4cf 100644
--- a/src/djankiserv/unki/sched.py
+++ b/src/djankiserv/unki/sched.py
@@ -272,12 +272,13 @@ class Scheduler:
     def emptyDyn(self, deck_id, limit=None):
         if not limit:
             limit = f"did = {deck_id}"
-        self.col.log(self.col.db.list(f"select id from cards where {limit}"))
+
+        #self.col.log(self.col.db.list(f"select id from cards where {limit}"))
         # move out of cram queue
         self.col.db.execute(
             f"""
             update cards set did = odid, queue = (case when type = 1 then 0
             else type end), type = (case when type = 1 then 0 else type end),
             due = odue, odue = 0, odid = 0, usn = %s where {limit}""",
-            self.col.usn(),
+            self.col.usn,
         )

self.col.log doesn't seem to be defined and usn is an integer, not a callable.
Now I have the dump of the database and the collection that raises the problem that I can attach to this issue, but I'll try to clean it up to a minimum.

@AntonOfTheWoods
Copy link
Contributor

Thanks @sandroden , I have created #11 which, if you Ok, should fix it.

@sandroden
Copy link
Author

I attach a minimum set of files to reproduce the error. I'm sorry I'm not able to create a test, I have to study first...
I leave it as documentation. Inside there's a README with some more info on how to sync. As already stated in the comment it's working now.
bug-emptyDyn.tar.gz

@AntonOfTheWoods
Copy link
Contributor

That is already a great help @sandroden , thanks! I'll try and get a test done tonight for Dyn decks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants