-
Notifications
You must be signed in to change notification settings - Fork 364
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
Possible deadlock when registering extensions and doing normal readWrites #371
Comments
Have you tried passing your own connection to registerExtension? On Fri, Oct 7, 2016 at 1:41 AM, cipherCOM notifications@github.com wrote:
|
I inspected the API you proposed and this let me realize, that the |
Okay got it tracked down. So here is what's happening: The problem would be that we actually pass our connection to
With this knowledge I'm not passing our connection to the Nevertheless the question remains: should the |
…n registration. This is no longer supported. In its place is a way of passing a connection 'config', which allows one to tweak the memory options of the internal database connection. This was the original motivation for the functionality (performance optimizations). Fixes issue #371
You're spot on with your deadlock assessment. Simply put, passing a custom connection to the registerExtension family of methods is unsafe. And there doesn't appear to be a safe way to fix this particular issue. At the heart of the matter is the order in which things are expected to occur when starting up the database system. Generally, people will do something like this: database = [[YapDatabase alloc] init...];
// async register extension #1
// async register extension #2
// ...
// continue with app launch When using an internal database connection for the registration connection, everything works nicely:
However, if passing a custom connection, the deadlock issue appears. Fixing the deadlock issue would create a separate bug:
So I've chosen to remove the functionality altogether. A custom connection can no longer be passed to the registerExtension family of methods. However, the original motivation for the feature had to do with performance optimizations. In particular, things like registering/updating a YapDatabaseView could cause a fair amount of thrashing if the objectCacheLimit is set too low. And so, to replace the previous functionality, the methods now allow you to pass an (optional) This allows you to pass memory settings, such as objectCacheLimit. Which achieves the original performance motivations. |
Thanks that you responded to the issue and solved it. I will have to check if this new API can be adapted by us (can't quite remember the context now) but I can totally understand that this is the way to go. Oh and kudos for the always detailed answers / documentation by your team. Very much appreciated! |
We're currently experiencing rare deadlocks with YapDatabase. I tried to inspect what internally happens and came to the following reasoning:
A normal readWrite will always go to through the connectionQueue first and then through the internal writeQueue. A comment is placed even directly above that the order matters.
The issue is that when using extension and registering them the framework internally goes a different way of acquiring locks. First the writeQueue and then the connectionQueue. This causes in my opinion the experienced locking problems if this happens simultaneously.
Would that really be a flaw of the framework or should we rather try to completely separate setup steps like registering extensions and accessing the DB?
The text was updated successfully, but these errors were encountered: