Closed kanjieater closed 3 years ago
The crash in anki seems to occur in Advance browser. However it only happens when ankiconnect hangs.
Debug info:
Anki 2.1.22 (0ecc189a) Python 3.8.0 Qt 5.14.1 PyQt 5.14.1
Platform: Windows 10
Flags: frz=True ao=True sv=1
Add-ons, last update check: 2020-11-25 18:28:09
Caught exception:
Traceback (most recent call last):
File "C:\Users\Micah\AppData\Roaming\Anki2\addons21\2055492159\__init__.py", line 77, in advance
self.server.advance()
File "C:\Users\Micah\AppData\Roaming\Anki2\addons21\2055492159\web.py", line 118, in advance
self.advanceClients()
File "C:\Users\Micah\AppData\Roaming\Anki2\addons21\2055492159\web.py", line 133, in advanceClients
self.clients = list(filter(lambda c: c.advance(), self.clients))
File "C:\Users\Micah\AppData\Roaming\Anki2\addons21\2055492159\web.py", line 133, in <lambda>
self.clients = list(filter(lambda c: c.advance(), self.clients))
File "C:\Users\Micah\AppData\Roaming\Anki2\addons21\2055492159\web.py", line 52, in advance
msg = self.sock.recv(recvSize)
ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
So I tried digging into this. I haven't figured it out how to fix it but the issue is clear.
When a WebClient's socket calls self.sock.recv it get no response from the client (in this situation where a client started a request then disconnected). Then the AnkiConnect's QTimer keeps advancing through the clients before a response comes from WebClient's recv.
I haven't managed to get clientSock.settimeout(5.0) to actually trigger and close the socket but I'm thinking that's what needs to be done.
Alright, I did get a working version but it's not very pretty: https://gist.github.com/kanjieater/7ae2e2c930a66604c4e011fe032367a3
The important thing is doing all your work in a single clientSock.recv request so the timeout can actually be applied, that's why the infinite while loop is required. If you keep context switching then it will never finish because the timeout resets on the socket (even if you initialize it outside). https://stackoverflow.com/questions/34371096/how-to-use-python-socket-settimeout-properly
Would that gist suffice as a PR? How can this be moved forward?
Please create a clean PR for this, and if everything looks good I'll merge it in.
By starting requests and then cancelling them Anki Connect will eventually stop responding.
Then while anki connect is frozen, after about 5-10mins I got this error from ankiconnect in anki:
ConnectionResetError: [WinError 10054] An Existing connection was forcibly closed by the host
That error popup then crashed anki and I couldn't even copy the text out of the error box, and had to copy it by hand while it was frozen - trying to get more detailed crash log, but I'm not sure how if the gui is crashing.
I'm doing basic cardInfo queries over localhost:
If I do multiple of these from the client I'm trying to use (GoldenDict) or open up a couple tabs with postman I can get this to happen. Start a query like the one above then cancel it and start another, eventually ankiconnect and anki freeze. It seems like anki stays working even while ankiconnect is frozen at first, but then both crash. It's easier to reproduce on large queries, so adding more card id's to the above can help reproduce.
Latest AnkiConnect version.
EDIT: I've attached an anki connect log file. Still no luck on getting an Anki Error log. You can see from this log that the card info is absolutely massive. It would be a good idea to allow clients to filter what fields they want to retrieve so they don't waste resources (in my case I don't need front/back but those are the largest!), but I'll open a different ticket for that. ankiconnect.log