Reputation: 2836
Clojure 1.5.1 and Core.async library version "0.1.267.0-0d7780-alpha" is used to run CPU intensive calculations. A bunch of functions wrapped by time out function thunk-timeout are sent to a channel as shown by below mock code.
(defn toSendToGo [args timeoutUnits]
(let [result (atom [false])
timeout? (atom false)]
(try
( thunk-timeout
(fn [] (reset! result (myFunction args))) timeoutUnits)
(catch java.util.concurrent.TimeoutException e (do (prn "!Time out after " timeoutUnits " seconds!!") (reset! timeout? true)) ))
(if @timeout? (do sth))
@result))
(let [c ( chan)]
(go (>! c (toSendToGo args timeoutUnits))))
On Linux server with large memory, the code runs fine without issue. On windows server with smaller memory, if a few cases in a row experienced time out, there'd be this strange exception that I don't quite understand. Why is this related to time out?
Exception in thread "my-async-dispatch-4" java.lang.IllegalStateException: Pop w
ithout matching push
at clojure.lang.Var.popThreadBindings(Var.java:364)
at clojure.core$pop_thread_bindings.invoke(core.clj:1737)
at regtest$fn__40$processRegtestFiles__41$fn__96$state_machine__3962__auto____97$fn__99.invoke(regtest.clj:158)
at regtest$fn__40$processRegtestFiles__41$fn__96$state_machine__3962__auto____97.invoke(regtest.clj:158)
at clojure.core.async.impl.ioc_macros$run_state_machine.invoke(ioc_macros.clj:945)
at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invoke(ioc_macros.clj:949)
at regtest$fn__40$processRegtestFiles__41$fn__96.invoke(regtest.clj:158)
at clojure.lang.AFn.run(AFn.java:24)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Exception in thread "my-async-dispatch-5" java.lang.IllegalStateException: Pop w
ithout matching push
at clojure.lang.Var.popThreadBindings(Var.java:364)
at clojure.core$pop_thread_bindings.invoke(core.clj:1737)
at regtest$fn__40$processRegtestFiles__41$fn__96$state_machine__3962__au
to____97$fn__99.invoke(regtest.clj:158)
at regtest$fn__40$processRegtestFiles__41$fn__96$state_machine__3962__au
to____97.invoke(regtest.clj:158)
at clojure.core.async.impl.ioc_macros$run_state_machine.invoke(ioc_macro
s.clj:945)
at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invoke(i
oc_macros.clj:949)
at regtest$fn__40$processRegtestFiles__41$fn__96.invoke(regtest.clj:158)
at clojure.lang.AFn.run(AFn.java:24)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
[UPDATE]
The issue is gone after adding a catch expression after the catch expression for TimeoutException:
(try...
(catch java.util.concurrent.TimeoutException e (do (prn "!Time out after " timeoutUnits " seconds!!") (reset! timeout? true)) )
(catch Exception e (prn "Unexpected exception " e) ))
With the caught exception being
Unexpected exception #<ExecutionException java.util.concurrent.ExecutionException: java.lang.NoClassDefFoundError: slingshot/Stone
Upvotes: 1
Views: 679
Reputation: 386
I'm not sure this is your problem but (toSendToGo) returns nil via the result atom if an exception is caught.
That nil is then put to chan c. Core.async channels shouldn't (and normally can't) have nil as a value. Do you still get the error when resetting result in the catch to anything but 'nil' (try 'false' perhaps?)?
As an aside, clojure, being a lisp, tends to prefer lower-case-with-hyphens for names of most things. toSendToGo should probably be to-send-to-go instead. I don't know of any official style guide but here's a link to the most thorough one I know of: https://github.com/bbatsov/clojure-style-guide
(P.S. This should probably have been a comment but I don't have the reputation to make them yet.)
Upvotes: 1