datalevin

Aleks 2024-09-30T16:18:28.699039Z

Hello! When I create a new client from dtlv repl, on the server log I see Added client #uuid ... for user ... Then if I exit the repl, this client isn't dropped. If any way to reuse it when I repl again? Or dropped it after leaving the repl. If no, seems like clients increases every time you created a new one.

Huahai 2024-10-05T00:42:24.178309Z

Unable to reproduce

Aleks 2024-09-30T16:40:54.614399Z

Now I get this

(show-clients dc)
Request to Datalevin server failed: "datalevin.datom.Datom cannot be cast to java.lang.Comparable"

Huahai 2024-09-30T17:42:24.492609Z

Idle clients are cleaned after a while.

Huahai 2024-09-30T17:43:36.418649Z

There's a thread on server dedicated to clean up resources.

Huahai 2024-09-30T17:46:12.400729Z

Note that there's no way to know if a client is dropped, e.g. the machine crashed, etc. Other than having a heartbeat (more expensive), cleaning up idle clients after a timeout is the cheapest solution.

Huahai 2024-09-30T17:46:57.629289Z

For the error, if you can have a reproducible case, that would be great.

Aleks 2024-09-30T18:49:00.504789Z

It's hard to say exactly steps to reproduce, but in general it looks like this: 1. start server with dtlv serv 2. get-conn from my app (for a normal user) 3. create a new client from dtlv repl (for datalevin user) 4. execute (show-clients ...) 2 times

Aleks 2024-09-30T18:49:33.799009Z

right now I've got it again

(def dc (new-client ""))
#'user/dc
(show-clients dc)
{#uuid "5beabc6e-6bae-42b8-b683-1a0e6750d553" {:ip "/127.0.0.1", :username "datalevin", :roles [:datalevin.role/datalevin], :permissions [[:datalevin.server/control :datalevin.server/server] [:datalevin.server/create :datalevin.server/database "foxcub"] [:datalevin.server/create :datalevin.server/database "foxcub"]], :open-dbs {"foxcub" {:datalog? true, :dbis #{}}}}, #uuid "a2e25e6c-03fb-403a-aa34-52ab9389f715" {:ip "/127.0.0.1", :username "datalevin", :roles [:datalevin.role/datalevin], :permissions [[:datalevin.server/control :datalevin.server/server] [:datalevin.server/create :datalevin.server/database "foxcub"] [:datalevin.server/create :datalevin.server/database "foxcub"]], :open-dbs {}}, #uuid "102a48a1-e522-4318-829c-d117797cf18b" {:ip "/127.0.0.1", :username "lava", :roles [:datalevin.role/lava], :permissions [[:datalevin.server/view :datalevin.server/role nil] [:datalevin.server/alter :datalevin.server/user "lava"] [:datalevin.server/alter :datalevin.server/database "foxcub"]], :open-dbs {"foxcub" {:datalog? true, :dbis #{}}}}}
(show-clients dc)
Request to Datalevin server failed: "datalevin.datom.Datom cannot be cast to java.lang.Comparable"
user>

Aleks 2024-09-30T18:50:34.312509Z

and stacktrace from the server

Request to Datalevin server failed: "datalevin.datom.Datom cannot be cast to java.lang.Comparable"
user>
                                                                      ...
                                                      clojure.core/map/fn                   core.clj: 2772
                                                  clojure.core/partial/fn                   core.clj: 2641
                                          datalevin.server/client-display                 server.clj: 1029
                                                      clojure.core/update                   core.clj: 6232
                                       datalevin.server/client-display/fn                 server.clj: 1032
                                                        clojure.core/mapv                   core.clj: 6971
                                                      clojure.core/reduce                   core.clj: 6886
                                                                      ...
                                                     clojure.core/mapv/fn                   core.clj: 6980
                                    datalevin.server/client-display/fn/fn                 server.clj: 1036
                                           datalevin.server/perm-tgt-name                 server.clj:  218
                                            datalevin.server/eid->db-name                 server.clj:  179
                                                  datalevin.pull-api/pull               pull_api.clj:  322
                                                  datalevin.pull-api/pull               pull_api.clj:  314
                                             datalevin.pull-api/pull-impl               pull_api.clj:  285
                                           datalevin.pull-api/attrs-frame               pull_api.clj:  268
                                            datalevin.db.DB/-range-datoms                     db.clj:  115
                                               datalevin.utl.LRUCache.put              LRUCache.java:   36
                                java.util.Collections$SynchronizedMap.put           Collections.java: 2598
                                                    java.util.HashMap.put               HashMap.java:  608
                                                 java.util.HashMap.putVal               HashMap.java:  640
                                             java.util.HashMap.treeifyBin               HashMap.java:  768
                                       java.util.HashMap$TreeNode.treeify               HashMap.java: 2000
                                     java.util.HashMap.compareComparables               HashMap.java:  373
                                                                      ...
java.lang.ClassCastException: datalevin.datom.Datom cannot be cast to java.lang.Comparable

Huahai 2024-09-30T18:51:24.984679Z

thanks, will take a look.

🙏🏻 1
Aleks 2024-09-30T19:17:20.307139Z

> cleaning up idle clients after a timeout is the cheapest solution I agree. Thanks for letting me know about this option