core-async

braai engineer 2022-11-07T14:47:55.226739Z

I get the following error when I attempt to compile my ClojureScript project for Release via shadow-cljs (running Node v16.16.0):

------ ERROR -------------------------------------------------------------------
 File: jar:file:/Users/petrus/.m2/repository/org/clojure/core.async/1.5.648/core.async-1.5.648.jar!/cljs/core/async.cljs:283:22
--------------------------------------------------------------------------------
 280 |                        true)))]
 281 |        (dotimes [_ n]
 282 |          (case type
 283 |            :compute  (go-loop []
----------------------------^---------------------------------------------------
Syntax error macroexpanding cljs.core/==.
ClassCastException: clojure.lang.KeywordLookupSite$1 incompatible with clojure.lang.IFn
	clojure.spec.alpha/spec-impl/reify--2053 (alpha.clj:930)
	clojure.spec.alpha/conform (alpha.clj:171)
	clojure.spec.alpha/conform (alpha.clj:167)
	clojure.spec.alpha/macroexpand-check (alpha.clj:708)
	clojure.spec.alpha/macroexpand-check (alpha.clj:704)

braai engineer 2022-11-07T14:50:48.397029Z

Solved: This seems to happen if you do shadow-cljs release while there is another shadow-cljs watch app instance running. Adding comment to GH issue here: https://github.com/thheller/shadow-cljs/issues/443

Alex Miller (Clojure team) 2022-11-07T14:57:30.436849Z

fyi, this may be unrelated but there were some longstanding issues with using Clojure with OpenJ9 on older Clojure versions - that was addressed in Clojure 1.10.2 so you should make sure your use of Clojure is β‰₯ that version

braai engineer 2022-11-07T15:01:29.710439Z

Thanks, @alexmiller. I’m running Clojure v1.11.1, ClojureScript v1.11.60 & core.async 1.5.648. This might be related to me defining the same Shadow-cljs release path as debug (watch) paths. Will try with different paths in case it’s clobbering something.

Daniel Gerson 2022-11-07T16:48:50.462679Z

I'm busy reading https://ask.clojure.org/index.php/10190/strategies-diagnosing-async-unexpectedly-blocking-thread and wishing I could name channels (chan :name :bob) even if the name would be 101:bob if it was instantiated repeatedly. Then I also wish I could enable trace logging for any time something went onto or came off all channels.

πŸ‘ 1
Daniel Gerson 2022-11-07T16:56:19.856759Z

Ooh, started watching... https://www.youtube.com/watch?v=oPv-TY_XQ60

2022-11-07T16:58:59.728589Z

Channels are not the thing to focus on there. Go blocks get translated into callbacks attached to go blocks or running on the go block pool, those callbacks are clojure function which end up with class names that reflect the current namespace when they were compiled

2022-11-07T17:00:43.662189Z

Ah, interesting, I thought the ask post was about blocking up the core.async threadpool

Daniel Gerson 2022-11-07T17:01:50.442699Z

Nope, as you've figured out the question is about reasoning about the "state machine" of your channels. The dude in the video is thinking along exactly the same lines as I am.

Daniel Gerson 2022-11-07T17:06:01.164809Z

Project doesn't look alive though πŸ€” https://github.com/LonoCloud/step.async

2022-11-07T17:07:01.317019Z

channels don't have a state machine

2022-11-07T17:07:09.208389Z

go blocks do

2022-11-07T17:07:43.926439Z

the channel ops that block a real thread <!! >!!, etc use promises

2022-11-07T17:08:10.555219Z

so in your stack traces from thread dumps they will show up as a deref of a promise

Daniel Gerson 2022-11-07T17:08:15.746479Z

I'm using the word to mean how ALL your channels changed across your various go blocks.

Daniel Gerson 2022-11-07T17:09:07.945209Z

Happy to say log of your channels instead.

2022-11-07T17:09:24.149939Z

and stacktraces from the thread dump will have associated file and line information (which isn't always perfect)

Daniel Gerson 2022-11-07T17:10:15.440299Z

I just want the history of what went into and out of all channels in order.

2022-11-07T17:11:02.207389Z

you may not want core.async then

2022-11-07T17:11:15.766829Z

channels have no order enforced between them

2022-11-07T17:11:35.071269Z

so if you want things in a global order, you would have to create one

Daniel Gerson 2022-11-07T17:11:36.412329Z

I don't want it while my programming is running, I want it only as a debug tool.

Daniel Gerson 2022-11-07T17:11:55.984579Z

Take a look at the video.

Daniel Gerson 2022-11-07T17:12:22.422349Z

Even if not identical, it's angling at the same goal.

2022-11-07T17:13:31.248509Z

I might at some point, but scrubbing through, he has channel operations that are not ordered between them, so he makes up an order

Daniel Gerson 2022-11-07T17:16:59.500329Z

Yeah, okay, he calls it a "step machine", so Freudian on my part. The output from a number of threads and 3 go blocks, multiple channels:

Daniel Gerson 2022-11-07T17:21:28.690899Z

And it doesn't matter to me if it's non-deterministic provided if the visual aid is the same as how it ran. It's a tool for identifying issues. I'm just happy that there are others that have been thinking along same lines πŸ™‚

Daniel Gerson 2022-11-07T17:44:20.052769Z

(yes I saw he has some ways of trying to force determinism)

phronmophobic 2022-11-07T18:35:28.271839Z

You may be interested in some of the jepsen libraries. They're built for analyzing the semantics of distributed databases, but I think some of the ideas can be applied to any asynchronous program: https://github.com/jepsen-io/maelstrom https://github.com/jepsen-io/elle

πŸ‘€ 1