forked from elan-ev/tobira
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix deadlock by using
scc
instead of dashmap
Fixes elan-ev#1129 The "frozen Tobira" bug was caused by the following: we had two in-memory hashmaps that cached different things. Each entry in that cache has a time stamp and is evicted/ignored once it is too old. The eviction is done by a long running task, that calls `retain` on the cache. Of course, the cache is also read. In the case of the user cache these steps are regularly performed: 1. Does an entry for this username exists? If yes: 2. Is this entry too old or differs from the new data? If yes: 3. Write new data to database. 4. Update the timestamp in the cache entry to mark it as "brand new". This tricky part is this: step 3 contains an `.await` point (waiting for the DB to reply). At that point, the Tokio runtime will pause that task and run a different task on that same thread. If that different task happens to be the maintenance task that calls `retain` on the hashmap, then we are in trouble: the documentation of `retain` says: > May deadlock if called when holding any sort of reference into the map And in [this issue](xacrimon/dashmap#233) it is specified, that this means: > May deadlock if called when **the current thread is** holding any sort > of reference into the map. That is usually not a problem in non-async multi-threaded code, but in async code when a lock/reference is held across an await point, then it can happen that the same thread holds a lock and tries to call `retain`. The solution is to not do that: avoid holding locks across await points (a good advice generally anyway). However, that isn't trivial in our case, but much more importantly: doing that is a subtle mistake! I don't want bugs like this cropping up accidentally again. I'm sure there is a clippy lint for that, but still, it feels wrong to me. So I decided to use a different library that does not have this problem. It's not yet as widely used but it seems very promising. The auth callback cache could also use `HashIndex`, which might be faster. But for simplicity I kept both `HashMaps` now. Should be plenty fast.
- Loading branch information
1 parent
7401998
commit 812c489
Showing
4 changed files
with
52 additions
and
42 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters