-
-
Save jeroenvandijk/13c6658b626f11491f84 to your computer and use it in GitHub Desktop.
Mocking datomic.Connection for fast in-memory testing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns bs.utils.mock-connection | |
"Utilities for using Datomic" | |
(:require [datomic.api :as d]) | |
(:use clojure.repl clojure.pprint) | |
(:import (java.util.concurrent BlockingQueue LinkedBlockingDeque) | |
(datomic Connection))) | |
(defrecord MockConnection | |
[dbAtom, ^BlockingQueue txQueue] | |
Connection | |
(db [this] @(.dbAtom this)) | |
(transact [this tx-data] (doto (datomic.promise/settable-future) | |
(deliver (let [tx-res | |
(loop [] | |
(let [db-atom (.dbAtom this) | |
old-val @db-atom | |
tx-res (d/with old-val tx-data) | |
new-val (:db-after tx-res)] | |
(if (compare-and-set! db-atom old-val new-val) | |
tx-res | |
(recur)) | |
))] | |
(.add ^BlockingQueue (.txQueue this) tx-res) | |
tx-res)) | |
)) | |
(transactAsync [this tx-data] (.transact this tx-data)) | |
(gcStorage [this olderThan]) | |
(requestIndex [this]) | |
(release [this]) | |
(sync [this] (doto (datomic.promise/settable-future) | |
(deliver (.db this)))) | |
(syncExcise [this t] (.sync this)) | |
(syncIndex [this t] (.sync this)) | |
(syncSchema [this t] (.sync this)) | |
(sync [this t] (.sync this)) | |
(txReportQueue [this] (.txQueue this))) | |
(defn ^Connection mock-conn | |
"Creates a mocked version of datomic.Connection which uses db/with internally. | |
Only supports datomic.api/db, datomic.api/transact and datomic.api/transact-async operations. | |
Sync and housekeeping methods are implemented as noops. #log() is not supported." | |
[db] | |
(MockConnection. (atom db) (LinkedBlockingDeque.))) | |
(comment ;; How fast is it ? | |
(def mem-db (bs.dev/local-db)) ;; creates a mem db, loads the schema and some fixture data in it. Takes about 20ms on my dev laptop. | |
(time (dotimes [i 1000] | |
(let [conn (mock-conn mem-db)] | |
@(d/transact conn [{:db/id (d/tempid :db.part/user) | |
:bouser/firstName (str "Valentinnnnn_" i) | |
:bouser/lastName (str "Valentinnnnn_" i) | |
:bouser/level "bandsquare" | |
:bouser/email (str "val.vvalval" i "@gmail.com") | |
}])))) | |
;; "Elapsed time: 2027.881 msecs". So this is a x10 improvement. | |
;; the schema and fixture data are quite small (35 attributes, 103 datoms), so I expect this will get more compelling as the application grows. | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment