Hello
I’m on “classic peer”
I have a datomic function :empty-query?
that I use as transaction function
(def empty-query?
(d/function '{:lang :clojure
:requires [[datomic.api :as d]]
:params [db query & args]
:code (when-not (->> (into [db] args)
(hash-map :query query :args)
(d/query)
(empty?))
(throw (ex-info "FAIL" {})))}))
But some queries produce different result’s on peer
and on transactor
For example
'[:find ?e
:in $ ?ignore-set
:where
[?e :app/foo]
(not [(contains? ?ignore-set ?e)])]
on peer
(d/with and d/transact on “mem”) works “as expected”
on transact
(d/transact on “dev”) always return “empty?”
Then I changed to
'[:find ?e
:in $ ?ignore-set
:where
[?e :app/foo]
[(contains? ?ignore-set ?e) ?q]
[(ground false) ?q]]
That second one always returns the same results (“as expected”) on transactor and on peer.
Is it a bug?
I don’t understand what exactly fails here.
You’re not invoking your empty-query?
function in either of the query examples you provide.
Thnks @marshall .
I’m using :empty-query
as a Transaction function
.
Example of use
(let [query '[:find ?e :where [?e :foo/bar]]]
(d/transact conn [[:empty-query query][:db/add "foo" :foo/bar "bar"]])
But some queries has different behaviors when running in datomic:mem
and datomic:dev
.
When I say “on peer
(d/with and d/transact on \“mem\”) works \“as expected\”” I’m saying that I have a tx-data
that contains a [:empty-query ...]
and when I transact
this tx-data
on datomic:mem
or make a d/with
on datomic:dev
, it works as I expected (fail the tx, for example). But when I d/transact
to datomic:dev
, then the transaction is completed successfully.
A repl-driven explanation
(def mem-conn (create-and-install-sample-set-1 "datomic:mem://foo"))
(def dev-conn (create-and-install-sample-set-1 "datomic:dev://localhost:4334/foo"))
(def tx-data [[:empty-query ....] [:db/add ...]])
;; I expect that this tx-data fails becaulse `[:empty-query ...]` will find results
(d/with (d/db mem-conn) tx-data) ;;; fail/throws; as expected
(d/with (d/db dev-conn) tx-data) ;;; fail/throws; as expected
@(d/transact mem-conn tx-data) ;;; fail/throws; as expected
@(d/transact dev-conn tx-data) ;; transact with success.; ???!!!????!!!
Then I change the query in :emtpty-query
from (first query on first post) to (second query on first post). I think that are both equivalents. But just the first do the issue. The second works “as expected” on “4” cenarios.
For testing purposes on a dev
transactor you should be able to include output statements (i.e. println
) inside your transaction function and they will print to stdout in the terminal where you’re running your transactor.
I would suggest examining the arguments and the constructed query to determine why the query isn’t returning your expected result. In general, this type of issue arises when using a ‘remote’ transactor because the arguments to a transaction function arrive as a Java type in the remote case (dev
), but not in the in-process case (mem
and with
).
Already did that
(prn [x (class x)])
all the things
The only relevant difference that I found was that (not [(contains? ?ignore-set ?e)])
turns into [not [[contains? ?ignore-set ?e]]]
.
The main problem is that in my tests on mem
it works and when I go production, it fail. And it is for concurrency problems.
I will make a repo to reproduce ASAP
Thanks for providing this.
We’re looking into the behavior.
@stu @marshall
Any news about that?
It will be fixed? There is a issue/tracking thing?