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

Deadlock in latest 3.4.0 #212

Closed
angelix opened this issue Mar 24, 2020 · 7 comments
Closed

Deadlock in latest 3.4.0 #212

angelix opened this issue Mar 24, 2020 · 7 comments
Assignees
Labels
Milestone

Comments

@angelix
Copy link

angelix commented Mar 24, 2020

In the recent release (3.4.0), my app is hanging in an upsert update (ObjectRepository)
Maybe is related to the changes made in #193.

@anidotnet
Copy link
Contributor

If you are using any locking mechanism to synchronize nitrite write, remove it. If not, please share a reproducible code.

@angelix
Copy link
Author

angelix commented Mar 25, 2020

It seems removing a lock from an outer method, fixed the issue, the locks where there from an implementation before using nitrite.
But why is this happening? How an app lock can mess the sync in nitrite?

Also, how this relates to issue #204

@anidotnet
Copy link
Contributor

In version 3.4.0 locking mechanism of nitrite has changed from 3.3.0. In 3.3.0 app developer needs to synchronize read-write and indexing separately, now from 3.4.0 it is managed by nitrite only. For upsert, update/insert and index write all are managed using a single ReentrantReadWriteLock in nitrite.

@angelix
Copy link
Author

angelix commented Mar 25, 2020

I was able to reproduce it. Try using 2 keys in an upsert update.

eg.

collection.update(Filters.and(eq("key", "key"), eq("second_key", "second_key")), doc, UpdateOptions.updateOptions(true));

If you need i can share the code, but its very easy reproducible.

I couldn't pass the invokeAll method in debug mode.

# AndFilters.java
List<Callable<Set<NitriteId>>> tasks = createTasks(filters, documentMap);

            boolean initialCount = true;
            List<Future<Set<NitriteId>>> futures = executorService.invokeAll(tasks);

@anidotnet
Copy link
Contributor

Did you run the above code with 3.4.0 or 3.3.0? I ran below test code on 3.4.0 and it went fine without any issues

@Test
public void testIssue212() {
    NitriteCollection collection = db.getCollection("test");
    Document doc1 = createDocument("key", "key").put("second_key", "second_key").put("third_key", "third_key");
    Document doc2 = createDocument("key", "key").put("second_key", "second_key").put("fourth_key", "fourth_key");
    Document doc = createDocument("fifth_key", "fifth_key");

    collection.insert(doc1, doc2);
    collection.update(Filters.and(Filters.eq("key", "key"),
        Filters.eq("second_key", "second_key")), doc, UpdateOptions.updateOptions(true));

    for (Document document : collection.find()) {
        System.out.println(document);
    }
}

@angelix
Copy link
Author

angelix commented Mar 25, 2020

Try adding indexes for both fields. Sorry, i didn't mention it previously.

if(!collection.hasIndex("key")){
         collection.createIndex("key", IndexOptions.indexOptions(IndexType.NonUnique));
}
if(!collection.hasIndex("second_key")){
        collection.createIndex("second_key", IndexOptions.indexOptions(IndexType.NonUnique));
}

@anidotnet
Copy link
Contributor

anidotnet commented Mar 25, 2020

Nice find.. I am going to give an emergency fix in version 3.4.1

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

No branches or pull requests

2 participants