Hello, I try to use https://github.com/replikativ/datahike-jdbc with socket-repl & chlorine and for to some reason evaluating a block with a transaction freeze the block in an endless evaluation (ie. the wheel keep turning) Any ideas where that comes from? If I do the same using nREPL it's working.
A transaction returns a record [1], I don't know if that's matter or not. [1] https://github.com/replikativ/datahike/blob/a6614482fc61483b82b7629716cace89f1f86b5e/src/datahike/db.cljc
@mauricio.szabo Might be able to point you at some debugging for that @jba but I can't think of a reason for a code block to just hang if it is valid code and executes fine directly in a REPL.
Probably because of UNREPL. There's an open issue on that - sometimes, it returns an invalid EDN and that freezes the whole evaluation (and sometimes, Chlorine itself - it only starts to eval again when you disconnect/reconnect)
Datahike is known to cause this issue, some datomic evaluation too 😞
Hmm, I've seen exceptions reported from unrepl but not hangs. Good to know. Or rather, bad to know, I guess.
Yes, look like what you are describing. Is it this issue https://github.com/Unrepl/unrepl/issues/52 ? What would be the way to debug it?
Probably the only way to debug is with tellnet. But if you're using datahike, is exactly the problem you're having - I remember having this exactly same problem with datahike, and having to change to nREPL to work with it 😞
good old network debugging, that's gonna be fun 😅 I will give it a try next week. Thanks for your work on chlorine btw, it's a great tool :)
536870913 :db/txInstant #inst \"2020-09-18T13:38:12.010-00:00\" 5" #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22549)}] {:bean {#unrepl/... nil #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22546)}}}] #unrepl/object [#unrepl/browsable [#unrepl.java/class [datahike.datom.Datom #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22551)}] #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22552)}] #datahike/Datom [1 :db/ident :city_name 536870913 true] "0x1e560feb" "#datahike/Datom [1 :db/ident :city_name 536870913 true]" {:bean {#unrepl/... nil #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22550)}}}] #unrepl/object [#unrepl/browsable [#unrepl.java/class [datahike.datom.Datom #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22554)}] #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22555)}] #datahike/Datom [1 :db/valueType :db.type/string 536870913 true] "0x1935e078" "#datahike/Datom [1 :db/valueType :db.type/string 536870913 true]" {:bean {#unrepl/... nil #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22553)}}}] #unrepl/object [#unrepl/browsable [#unrepl.java/class [#unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22558)}] #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22559)}] #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22560)}]], #unrepl/... nil #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22561)}} 38]
[:prompt {:file "/home/jba/PROJECTS/playground/src/playground/db.clj", :line 29, :column 2, :offset 1576, clojure.core/*warn-on-reflection* false, clojure.core/*ns* #unrepl/browsable [#unrepl/ns playground.db #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22562)}]} 39]
[:prompt {:file "/home/jba/PROJECTS/playground/src/playground/db.clj", :line 30, :column 1, :offset 1577, clojure.core/*warn-on-reflection* false, clojure.core/*ns* #unrepl/browsable [#unrepl/ns playground.db #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22563)}]} 40]
Could it be that https://github.com/mauricioszabo/repl-tooling/blob/4d49f865b2ec22077282638788f552a5b1299087/src/repl_tooling/editor_helpers.cljs#L101 need to implement this ...
? @mauricio.szabo
unrepl/...
is reference here: https://github.com/Unrepl/unrepl/blob/fa946eef88b0516dab81c8a9b3d8f9fcff06f44b/src/unrepl/printer.clj
for the same eval nrepl return:
{:db-before ...
:db-after ...
:tx-data [#datahike/Datom [536870915 :db/txInstant #inst "2020-09-18T14:11:11.183-00:00" 536870915 true]], :tempids {:db/current-tx 536870915}
Not really - search for a place that returns :eval
on wireshark. You'll see that the second argument of the vector that starts with :eval
is a map that have duplicated keys
that's the full eval:
[:eval #datahike.db.TxReport {:db-before #datahike.db.DB {}, :db-after #datahike.db.DB {1 :db/cardinality, 1 :db/ident, 1 :db/valueType, 536870913 :db/txInstant}, :tx-data [#unrepl/object [#unrepl/browsable [#unrepl.java/class [datahike.datom.Datom #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22547)}] #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22548)}] #datahike/Datom [536870913 :db/txInstant #inst "2020-09-18T13:38:12.010-00:00" 536870913 true] "0x707efc8b" #unrepl/string ["#datahike/Datom [536870913 :db/txInstant #inst \"2020-09-18T13:38:12.010-00:00\" 5" #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22549)}] {:bean {#unrepl/... nil #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22546)}}}] #unrepl/object [#unrepl/browsable [#unrepl.java/class [datahike.datom.Datom #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22551)}] #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22552)}] #datahike/Datom [1 :db/ident :city_name 536870913 true] "0x1e560feb" "#datahike/Datom [1 :db/ident :city_name 536870913 true]" {:bean {#unrepl/... nil #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22550)}}}] #unrepl/object [#unrepl/browsable [#unrepl.java/class [datahike.datom.Datom #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22554)}] #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22555)}] #datahike/Datom [1 :db/valueType :db.type/string 536870913 true] "0x1935e078" "#datahike/Datom [1 :db/valueType :db.type/string 536870913 true]" {:bean {#unrepl/... nil #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22553)}}}] #unrepl/object [#unrepl/browsable [#unrepl.java/class [#unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22558)}] #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22559)}] #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22560)}]], #unrepl/... nil #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22561)}} 38]
[:prompt {:file "/home/jba/PROJECTS/playground/src/playground/db.clj", :line 29, :column 2, :offset 1576, clojure.core/*warn-on-reflection* false, clojure.core/*ns* #unrepl/browsable [#unrepl/ns playground.db #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22562)}]} 39]
try to indent it correctly:
[:eval #datahike.db.TxReport
{:db-before #datahike.db.DB {},
:db-after #datahike.db.DB {1 :db/cardinality, 1 :db/ident, 1 :db/valueType, 536870913 :db/txInstant},
:tx-data [#unrepl/object [#unrepl/browsable [#unrepl.java/class [datahike.datom.Datom #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22547)}]
#unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22548)}]
#datahike/Datom [536870913 :db/txInstant #inst "2020-09-18T13:38:12.010-00:00" 536870913 true] "0x707efc8b"
#unrepl/string ["#datahike/Datom [536870913 :db/txInstant #inst \"2020-09-18T13:38:12.010-00:00\" 5"
#unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22549)}] {:bean {#unrepl/... nil
#unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22546)}}}]
#unrepl/object [#unrepl/browsable [#unrepl.java/class [datahike.datom.Datom #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22551)}]
#unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22552)}]
#datahike/Datom [1 :db/ident :city_name 536870913 true] "0x1e560feb" "#datahike/Datom [1 :db/ident :city_name 536870913 true]" {:bean {#unrepl/... nil
#unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22550)}}}]
#unrepl/object [#unrepl/browsable [#unrepl.java/class [datahike.datom.Datom #unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22554)}]
#unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22555)}]
#datahike/Datom [1 :db/valueType :db.type/string 536870913 true] "0x1935e078" "#datahike/Datom [1 :db/valueType :db.type/string 536870913 true]" {:bean {#unrepl/... nil
#unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22553)}}}]
#unrepl/object [#unrepl/browsable [#unrepl.java/class [#unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22558)}]
#unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22559)}]
#unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22560)}]],
#unrepl/... nil
#unrepl/... {:get (unrepl.repl$i9hjMxfOQ2IzbCA5TVia2QQEJNg/fetch :G__22561)}} 38]
I see it now, it's coming from :db-after #datahike.db.DB {1 :db/cardinality, 1 :db/ident, 1 :db/valueType, 536870913 :db/txInstant}
?
Yes, if you use pr-str
, this error does not occur. To be honest, I have no idea why it happens with UNREPL
nrepl return this `{:db-after #datahike/DB {:schema {:db/ident {:db/unique :db.unique/identity}, :city_name {:db/ident :city_name, :db/valueType :db.type/string, :db/cardinality :db.cardinality/one}, 1 :city_name}}}
for continuing the investigation I should try to reproduce it from a vanilla unrepl?
I think it's easier to reproduce from a vanilla unrepl - you won't need the wireshark at all, only telnet and copy-pasting the UNREPL blob over the telnet connection
The UNREPL blob is literally the contents of this file: https://github.com/mauricioszabo/repl-tooling/blob/master/resources/unrepl.clj
Well, to be honest I'm giving up UNREPL, it's too complicated 😞. The only problem is to find out something that allows for evaluation (by sending file/row infmroation) and break.... so far, only UNREPL and nREPL allows that...
I would imagine you could setup something fairly simple that allows for interruption of execution using a future or similar? I guess the bigger problem is interrupted very large results coming back from the evaluation?
I believe interruption with future, for example, is quite simple. The problem is the coordination - because I need to somehow "store" the future to be able to cancel it later, and it needs to be persisted between multiple connections. But the file + row is harder :(