Skip to content

Fix persistence across restart! on JDBC backend #194

@acobster

Description

@acobster

Connection is leaking from Datahike/konserve's JDBC backend. On subsequent queries, Datahike's writer thread is shutting down:

20 ; (err) 2025-12-31T22:04:19.055Z clementine ERROR [datahike.writer:132] - Writer thread shutting down because of commit error. #error {                                                                                                   
21 ; (err)  :cause "com.mchange.v2.c3p0.ComboPooledDataSource[ identityToken -> ... ] has been closed() -- you can no longer use it."

Repro by simply commenting out :recreate? true in dev/main.edn and starting, then restarting, the application.

Full stack trace:

; eval (current-form): (restart! (-> "dev/main.edn" aero/read-config))
; (out) 2025-12-31T22:04:14.992Z clementine INFO [systems.bread.alpha.cms.main:311] - releasing auth session-store connection
; (out) 2025-12-31T22:04:14.997Z clementine INFO [systems.bread.alpha.cms.main:319] - initializing :bread/db with config: {:schema-flexibility :write, :keep-history? true, :store {:backend :jdbc, :dbtype "sqlite", :user "bread", :password "bread", :dbname "bread.db"}}
; (out) 2025-12-31T22:04:14.999Z clementine INFO [systems.bread.alpha.database:62] - database already exists
; (out) 2025-12-31T22:04:15.000Z clementine INFO [systems.bread.alpha.database:172] - checking 13 migrations
; (out) 2025-12-31T22:04:15.006Z clementine INFO [systems.bread.alpha.cms.main:303] - connecting auth session-store: datahike.connector.Connection@2ee1b879
; (out) 2025-12-31T22:04:15.007Z clementine INFO [systems.bread.alpha.cms.main:291] - setting ring-defaults session store: #object[systems.bread.alpha.plugin.auth.DatalogSessionStore 0x1a1d4ed1 "systems.bread.alpha.plugin.auth.DatalogSessionStore@1a1d4ed1"]
; (out) Starting HTTP server on port 1312
true
; --------------------------------------------------------------------------------
; eval (current-form): (restart! (-> "dev/main.edn" aero/read-config))
; (out) 2025-12-31T22:04:17.436Z clementine INFO [systems.bread.alpha.cms.main:311] - releasing auth session-store connection
; (out) 2025-12-31T22:04:17.442Z clementine INFO [systems.bread.alpha.cms.main:319] - initializing :bread/db with config: {:schema-flexibility :write, :keep-history? true, :store {:backend :jdbc, :dbtype "sqlite", :user "bread", :password "bread", :dbname "bread.db"}}
; (out) 2025-12-31T22:04:17.450Z clementine INFO [systems.bread.alpha.database:62] - database already exists
; (out) 2025-12-31T22:04:17.452Z clementine INFO [systems.bread.alpha.database:172] - checking 13 migrations
; (out) 2025-12-31T22:04:17.459Z clementine INFO [systems.bread.alpha.cms.main:303] - connecting auth session-store: datahike.connector.Connection@2ee1b879
; (out) 2025-12-31T22:04:17.459Z clementine INFO [systems.bread.alpha.cms.main:291] - setting ring-defaults session store: #object[systems.bread.alpha.plugin.auth.DatalogSessionStore 0x63a4dbbc "systems.bread.alpha.plugin.auth.DatalogSessionStore@63a4dbbc"]
; (out) Starting HTTP server on port 1312
true
; (err) 2025-12-31T22:04:19.055Z clementine ERROR [datahike.writer:132] - Writer thread shutting down because of commit error. #error {
; (err)  :cause "com.mchange.v2.c3p0.ComboPooledDataSource[ identityToken -> z8kflubfwv1g191590lzg|126372d5, dataSourceName -> z8kflubfwv1g191590lzg|126372d5 ] has been closed() -- you can no longer use it."
; (err)  :via
; (err)  [{:type clojure.lang.ExceptionInfo
; (err)    :message "com.mchange.v2.c3p0.ComboPooledDataSource[ identityToken -> z8kflubfwv1g191590lzg|126372d5, dataSourceName -> z8kflubfwv1g191590lzg|126372d5 ] has been closed() -- you can no longer use it."
; (err)    :data {}
; (err)    :at [superv.async$throw_if_exception_ invokeStatic "async.cljc" 93]}
; (err)   {:type java.sql.SQLException
; (err)    :message "com.mchange.v2.c3p0.ComboPooledDataSource[ identityToken -> z8kflubfwv1g191590lzg|126372d5, dataSourceName -> z8kflubfwv1g191590lzg|126372d5 ] has been closed() -- you can no longer use it."
; (err)    :at [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource assertCpds "AbstractPoolBackedDataSource.java" 512]}]
; (err)  :trace
; (err)  [[com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource assertCpds "AbstractPoolBackedDataSource.java" 512]
; (err)   [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager "AbstractPoolBackedDataSource.java" 524]
; (err)   [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getConnection "AbstractPoolBackedDataSource.java" 140]
; (err)   [next.jdbc.connection$make_connection invokeStatic "connection.clj" 452]
; (err)   [next.jdbc.connection$make_connection invoke "connection.clj" 436]
; (err)   [next.jdbc.connection$eval54899$fn__54900 invoke "connection.clj" 481]
; (err)   [next.jdbc.protocols$eval54629$fn__54630$G__54620__54637 invoke "protocols.clj" 25]
; (err)   [next.jdbc.result_set$eval55602$fn__55610 invoke "result_set.clj" 934]
; (err)   [next.jdbc.protocols$eval54661$fn__54662$G__54652__54671 invoke "protocols.clj" 34]
; (err)   [next.jdbc$execute_BANG_ invokeStatic "jdbc.clj" 251]
; (err)   [next.jdbc$execute_BANG_ invoke "jdbc.clj" 238]
; (err)   [konserve_jdbc.core.JDBCTable _blob_exists_QMARK_ "core.clj" 220]
; (err)   [konserve.impl.defaults.DefaultStore _exists_QMARK_ "defaults.cljc" 372]
; (err)   [konserve.impl.defaults.DefaultStore _get_in "defaults.cljc" 381]
; (err)   [konserve.core$get_in invokeStatic "core.cljc" 82]
; (err)   [konserve.core$get_in invoke "core.cljc" 73]
; (err)   [konserve.core$get invokeStatic "core.cljc" 96]
; (err)   [konserve.core$get invoke "core.cljc" 88]
; (err)   [datahike.writing$branch_heads_as_commits$iter__47284__47288$fn__47289 invoke "writing.cljc" 126]
; (err)   [clojure.lang.LazySeq sval "LazySeq.java" 42]
; (err)   [clojure.lang.LazySeq seq "LazySeq.java" 51]
; (err)   [clojure.lang.RT seq "RT.java" 535]
; (err)   [clojure.core$seq__5467 invokeStatic "core.clj" 139]
; (err)   [clojure.core$dorun invokeStatic "core.clj" 3134]
; (err)   [clojure.core$doall invokeStatic "core.clj" 3149]
; (err)   [clojure.core$doall invoke "core.clj" 3149]
; (err)   [datahike.writing$branch_heads_as_commits invokeStatic "writing.cljc" 119]
; (err)   [datahike.writing$branch_heads_as_commits invoke "writing.cljc" 118]
; (err)   [datahike.writing$commit_BANG_$fn__47608$state_machine__13571__auto____47615$fn__47617 invoke "writing.cljc" 156]
; (err)   [datahike.writing$commit_BANG_$fn__47608$state_machine__13571__auto____47615 invoke "writing.cljc" 153]
; (err)   [clojure.core.async.impl.ioc_macros$run_state_machine invokeStatic "ioc_macros.clj" 978]
; (err)   [clojure.core.async.impl.ioc_macros$run_state_machine invoke "ioc_macros.clj" 977]
; (err)   [clojure.core.async.impl.ioc_macros$run_state_machine_wrapped invokeStatic "ioc_macros.clj" 982]
; (err)   [clojure.core.async.impl.ioc_macros$run_state_machine_wrapped invoke "ioc_macros.clj" 980]
; (err)   [datahike.writing$commit_BANG_$fn__47608 invoke "writing.cljc" 153]
; (err)   [clojure.lang.AFn run "AFn.java" 22]
; (err)   [java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1144]
; (err)   [java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 642]
; (err)   [clojure.core.async.impl.concurrent$counted_thread_factory$reify__8183$fn__8184 invoke "concurrent.clj" 29]
; (err)   [clojure.lang.AFn run "AFn.java" 22]
; (err)   [java.lang.Thread run "Thread.java" 1583]]}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions