datascript icon indicating copy to clipboard operation
datascript copied to clipboard

equality on ^Entity bypasses db

Open dustingetz opened this issue 2 years ago • 1 comments

Here: https://github.com/tonsky/datascript/blob/6de343b1b3aecb95c21fbe46384face3f99b989b/src/datascript/impl/entity.cljc#L156

This breaks reactive programming semantics where, when db updates, (d/entity db x) updates but the result is = to the prior result and therefore continuous time reactive engines will skip downstream computation, reusing a buffered prior instance of the entity that is inconsistent with the latest db.

Appears to have been introduced in https://github.com/tonsky/datascript/commit/8264eb0efa500084b24654d1d2f9b69ef1d3f25f , and seems not deeply considered – will you accept a PR uncommenting that check? What needs to be tested?

dustingetz avatar Aug 08 '22 15:08 dustingetz

I don’t remember why we removed db check here. But comparing DBs might be expensive. How about identical? here? Would that work for you?

tonsky avatar Aug 08 '22 16:08 tonsky

Provided fix accounts for db in entity equality, using identical?.

The following test is interesting. It shows this is not a perfect solution, but the tradeoff is acceptable for us.

(deftest test-entity-equality
  (let [db1 (-> (d/empty-db {})
              (d/db-with [{:db/id 1, :name "Ivan"}]))
        db2 (d/db-with db1 [])]
    (testing "Two entities are equal if they have the same :db/id and refer to the same database"
      (is (= db1 db2))
      (is (not= (d/entity db1 1) (d/entity db2 1))))))

ggeoffrey avatar Aug 15 '22 12:08 ggeoffrey

Thanks! Pushed 1.3.14

tonsky avatar Aug 15 '22 20:08 tonsky