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

Some browsers throw TransactionInactiveError during login #101

Closed
bwindels opened this issue Sep 18, 2020 · 4 comments · Fixed by #118
Closed

Some browsers throw TransactionInactiveError during login #101

bwindels opened this issue Sep 18, 2020 · 4 comments · Fixed by #118
Assignees

Comments

@bwindels
Copy link
Contributor

bwindels commented Sep 18, 2020

Some browsers throw TransactionInactiveError during login:

  • GNOME Web up to 3.36.4
  • Internet explorer 11 up to 11.0.9600.18860 on Windows 7 (but not 11.1339.17763.0 on Windows 10)
  • Safari up to 13.1 on macOS 10.15.4

I'm not a 100% they fail at the same point during login though, but it is possible.

The assumption is that these browsers don't wait for microtasks to complete before closing an indexeddb transaction. I've played around with a promise polyfill that uses mutationobserver to schedule a microtask (confirmed on https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/ it does get scheduled before setTimeout) but this still didn't fix the issue, leading me to think that IE11 in that case wasn't actually waiting for any scheduled microtask to finish before closing the transaction.

If the above is the case, what can we do (apart from not using promises for idb, which isn't really feasible at this point):

  • make a prototype with a small idb example using promises and debug it on the above browsers.
  • debug more which calls fail exactly, and if any preceding calls succeeded, and see if we can explain that with the above understanding. We'd need more logging for this.
  • use special promises that resolve/reject synchronous for idb stuff on these browsers?
  • use promises for idb with a manual flush as suggested here
@bwindels
Copy link
Contributor Author

dexie/Dexie.js#317

@bwindels
Copy link
Contributor Author

https://gist.github.com/bwindels/f4ec90192f07f675d55c9db438960ac9 works in all browsers mentioned above apart from IE11 on Win7...

@bwindels bwindels changed the title Some browsers throw TransactionInactiveError during login Make it work on IE11/Windows 7 Sep 24, 2020
@bwindels bwindels changed the title Make it work on IE11/Windows 7 Some browsers throw TransactionInactiveError during login Sep 24, 2020
@bwindels
Copy link
Contributor Author

bwindels commented Sep 25, 2020

So IE11 on Windows 7 (and not on Windows 10) needs to have the promise queue flushed synchronously from the idb event handler, and then it works. There's a prototype of this on the branch bwindels/idb-promises. It is using a promise implementation that might not be ready for production usage, so we might need to find another one where we can add a manual flush easily. Also, we need to prevent the core-js one from being included.

As a representative of the other browsers above I've tested with Gnome Web and I can get it to go a lot further when I make the readTxn and readWriteTxn methods on the storage synchronous. I could not recreate the failure mode in the prototype (idb-promises-es6.html) though.

There is a prototype of implementing this in the app on the branch bwindels/idb-promises-txn. It still fails though on the first operation in session.writeSync as there the transaction once again has become inactive. To make things worse, the transaction is committed at this point, so the store will be in an inconsistent state (e.g. the room sync changes got stored, but the sync token didn't). We could detect this better by keeping a list of all requests we generally don't await to the transaction (add, put, delete, ...) (and should perhaps not create a promise for), and when awaiting txn.complete(), check that all of those have succeeded.

@bwindels bwindels self-assigned this Sep 28, 2020
@bwindels
Copy link
Contributor Author

Went for es6-promise polyfill, with stefanpenner/es6-promise#362 being the PR to expose flush functionality. Work with fork at https://github.com/bwindels/es6-promise for now.

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

Successfully merging a pull request may close this issue.

1 participant