datalevin 2025-08-26

Does datalevin support querying the same database across multiple threads? I am getting a java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Comparison method violates its general contract! error occasionally

Interesting, could you please provide some code to reproduce the issue?

I can't it reproduce with mock data, maybe it is a data issue, just curious that it would happen sometimes but not others (with the same query and same data)

Querying the same database across multiple threads is the intended use case. The error you are seeing is likely a data problem. what the thread dump looks like, maybe you can post the part of the trace where DL got stuck?

It's not using a numeric attribute that might sometimes contain ##NaN or ##Inf, is it?

I don’t think so, as far as I know the problem only occurs when running multiple queries simultaneously, the same queries run one at a time don’t error. It also doesn’t error every time, it’s hard to track down.

Either this or some other issue I have in my prod database caused queries to lock up, the thread dump said datalevin got stuck planning the query, which is what made me question if parallelism was the issue

Here is the thread dump where it gets stuck

"async-dispatch-1" #28 [2978694] daemon prio=5 os_prio=0 cpu=19962.55ms elapsed=2076549.76s tid=0x00007fdf498b2110 nid=2978694 waiting on condition [0x00007fdf2cdd6000] java.lang.Thread.State: WAITING (parking) at jdk.internal.misc.Unsafe.park(java.base@21.0.7/Native Method) - parking to wait for <0x00000000a7a21e20> (a java.util.concurrent.FutureTask) at java.util.concurrent.locks.LockSupport.park(java.base@21.0.7/LockSupport.java:221) at java.util.concurrent.FutureTask.awaitDone(java.base@21.0.7/FutureTask.java:500) at java.util.concurrent.FutureTask.get(java.base@21.0.7/FutureTask.java:190) at java.util.concurrent.AbstractExecutorService.invokeAll(java.base@21.0.7/AbstractExecutorService.java:252) at datalevin.util$map_PLUS_.invokeStatic(util.clj:631) at datalevin.util$map_PLUS_.invoke(util.clj:627) at datalevin.query$update_nodes.invokeStatic(query.clj:1660) at datalevin.query$update_nodes.invoke(query.clj:1656) at datalevin.query$build_plan$fn__35597.invoke(query.clj:1979) at clojure.lang.PersistentArrayMap.kvreduce(PersistentArrayMap.java:475) at clojure.core$fn__8555.invokeStatic(core.clj:6987) at clojure.core$fn__8555.invoke(core.clj:6967) at clojure.core.protocols$fn__8283$G__8278__8292.invoke(protocols.clj:174) at clojure.core$reduce_kv.invokeStatic(core.clj:6998) at clojure.core$reduce_kv.invoke(core.clj:6989) at datalevin.query$build_plan.invokeStatic(query.clj:1973) at datalevin.query$build_plan.invoke(query.clj:1956) at datalevin.query$planning.invokeStatic(query.clj:2087) at datalevin.query$planning.invoke(query.clj:2085) at datalevin.query$_q.invokeStatic(query.clj:2095) at datalevin.query$_q.invoke(query.clj:2092) at datalevin.query$q_STAR_.invokeStatic(query.clj:2376) at datalevin.query$q_STAR_.invoke(query.clj:2359) at datalevin.query$q_result.invokeStatic(query.clj:2411) at datalevin.query$q_result.invoke(query.clj:2401) at datalevin.query$q.invokeStatic(query.clj:2427) at datalevin.query$q.doInvoke(query.clj:2423) at clojure.lang.RestFn.applyTo(RestFn.java:142) at clojure.core$apply.invokeStatic(core.clj:669) at clojure.core$apply.invoke(core.clj:662) at datalevin.core$q.invokeStatic(core.clj:431) at datalevin.core$q.doInvoke(core.clj:413) at clojure.lang.RestFn.applyTo(RestFn.java:142) at clojure.core$apply.invokeStatic(core.clj:671) at clojure.core$apply.invoke(core.clj:662) at 

yea indeed, same Exception, but certainly different errors/stack-traces; i was wondering if a root cause--beneath the differences--was ever exposed that might fit my occurrence- Comparison method violates its general contract seems to be a pretty rare exception judging by the slack history (this thread was only 1 of 3 occurrences!)

I know this is quite a necrobump, but did anything come of this? Got this error for the first time last night, and running the same query this morning on the same data worked as originally expected- I'll add that this was on a test database, and so was the only query being run at both times (I'm wondering if it would make sense for me to just retry all queries that encounter this specific error, if it happens to just be a consistent matter of luck.) The stack-trace is a bit opaque to me, but i'll append it in a snippet here If the theory is that its a data issue, is there anything specific I can look for to find what that problematic data is?

I forget exactly if we totally solved it. We added our own semaphore to prevent any cross thread access of a datalevin database

You might have had it from cross thread access last night but not this morning? as far as I can remember the bug is very hard to trigger, even with the right data and query. I think I had to run it thousands of times to get a few errors

Don't think so, it was a lonely night in the office for me- maybe it was just RNG, I always did consider myself lucky 😅 i'll see if i ever manage to trigger it again

I'm also on an older 0.9.x version, so maybe the current error is different than mine

These errors are quite different.