i've been playing around with flow + flow-monitor and it's been really enjoyable so far!
i have some feedback:
• flow-monitor doesn't clean up its report-monitoring thread on stop which means you cannot inspect any subsequent errors without restarting your flow
• speaking of errors, there seems to be a bug in flow-monitor as it's not showing errors (see 🧵)
• it'd be really nice if we could do more than filter state in flow-monitor (i.e. if my state contains a list of a 1000 items, i may want to (update state :items count) instead of just filtering the key)
• the flow library throws when it encounters an outid that wasn't defined when processing outs from a transform step. this feels slightly unintuitive given how clojure maps are generally treated as "open" (admittedly, this was likely exacerbated by the flow-monitor error issues i mentioned above).
v0.1.5 is out now and the visuals should be improved. The proc state panel in the monitor is now a collapsible tree instead of just flat text, the max width is also now limited so they won’t stretch across the screen. in/outs also show the ns if present.
on flow-monitor v0.1.3, this flow does not show exceptions for me
(defn throw!
[msg]
(throw (ex-info "test exception" {:msg msg})))
(def f (flow/create-flow
{:procs {:input {:proc (flow/process (flow/lift1->step identity))}
:thrower {:proc (flow/process (flow/lift1->step #'throw!))}}
:conns [[[:input :out] [:thrower :in]]]}))
there are no console errors in either brave/firefox.
if i run that flow and not the monitor, i see the exception on the error chan as expected
flow> (async/poll! (:error-chan chs))
{:clojure.core.async.flow/pid :thrower,
:clojure.core.async.flow/status :running,
:clojure.core.async.flow/state nil,
:clojure.core.async.flow/count 1,
:clojure.core.async.flow/cid :in,
:clojure.core.async.flow/msg "hi",
:clojure.core.async.flow/op :step,
:clojure.core.async.flow/ex #error {
:cause "test exception"
:data {:msg "hi"}
:via
[{:type clojure.lang.ExceptionInfo
:message "test exception"
:data {:msg "hi"}
:at [flow$fn__32793 invokeStatic "flow.clj" 189]}]
:trace
[[flow$fn__32793 invokeStatic "flow.clj" 189]
[flow$fn__32793 invoke "flow.clj" 189]
[clojure.core.async.flow$lift1__GT_step$fn__12644 invoke "flow.clj" 296]
[clojure.core.async.flow.impl$proc$reify__12575$run__12580$fn__12586 invoke "impl.clj" 280]
[clojure.core.async.flow.impl$proc$reify__12575$run__12580 invoke "impl.clj" 260]
[clojure.lang.AFn applyToHelper "AFn.java" 152]
[clojure.lang.AFn applyTo "AFn.java" 144]
[clojure.core$apply invokeStatic "core.clj" 667]
[clojure.core$apply invoke "core.clj" 662]
[clojure.core.async.flow.impl$futurize$fn__12404$fn__12405 invoke "impl.clj" 34]
[clojure.lang.AFn call "AFn.java" 18]
[java.util.concurrent.FutureTask run "FutureTask.java" 328]
[java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1090]
[java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 614]
[java.lang.Thread run "Thread.java" 1474]]}}• You are correct about report-monitoring not fully cleaning up and letting go of the channels. I will fix that and cut a new release.
• The monitor does actually show the errors and where they came from. I used your throw! example. Here is the full example I used and screenshots of how it renders.
On your third point. The monitor is intended to provide a user interface for things you can actually do with flow, and provide visuals for things that may be hard to see as data. The overall status of channel back pressure in your flow, for example. So at the moment, manipulating state beyond filtering hasn’t been in scope. However, I will keep it in mind as both projects evolve.
Lastly, I believe the error with nonexistent out ids isn’t related to maps, but asking to write to channels that don’t exist. Fortunately, those should be pretty easy to spot, and flow monitor does display the error and which proc it is coming from.
Thanks for the feedback! I’ll ping you when the next release is out with the improved stop-server function.
hmm, using your example i'm still not seeing anything related to errors in the UI. let me start a whole new project and see what happens
ah, there we go. it only seems to work in chrome
brave/firefox doesn't show error information and the coloring of the channel buffers is hit or miss
but chrome seems to work
Ahh, good to know. I had to do extra work to get the ui functional in firefox initially (the svg drawing didn’t want to play nicely) and I guess I wasn’t actively testing there for later iterations of the project. I will add that to the todo queue.
i am seeing some errors now in the brave session, so it may all be a red-herring. honestly not sure what's going on, sorry. i've been messing with a much more complex flow all day and never saw errors in the UI 🤔
i wonder if it's a timing/cadence issue. the other flow does a lot of stuff and so maybe messages/UI state is getting dropped somewhere? ¯\(ツ)/¯
regardless, i appreciate your work on it!
Good deal. For what it is worth I just tested in firefox and it is outputting as expected. Let us know if you run into anything else.
> the svg drawing didn’t want to play nicely i've noticed the UI connections can get into a pretty weird state when a proc's state is really wide. it fixes itself once the a new web-socket message is put handled
also namespaces for in/out ids are being elided
There is a new https://github.com/clojure/core.async.flow-monitor/releases/tag/v0.1.4 that lets go of the reporting channels when you stop the monitor. I need to make some styling changes to try to control the really wide state displays. At the moment it does its best to catch up and redraw, but it certainly can look wonky for a few seconds in some scenarios. I will review the ns issue.