Question

I've written a standalone uberjar with a main method that spins off two go blocks like so:

(defn -main [& args]
  (let [c (chan)]
    (go (while true
           (>! c (rand))))
    (go (while true
           (<! c)))))

But when I execute the program it quickly terminates. Why? My intention is to have the go blocks execute indefinitely. I ended up sticking

 (<!! (chan))

at the end of the main function to prevent termination. Is there a better way to do that?

Was it helpful?

Solution

The program terminates because, after those go blocks are created, the main function is finished. With nothing to do, it exits; that shouldn't be much of a surprise. Of course, we'd prefer the main application keep running while all of those go blocks are still alive.

Each of those go blocks produces a channel; you could wait until one of them returns something (though as it stands, they never will). Try blocking with alts!! while they spin:

(defn -main
  [& args]
  (let [c (chan)]
    (alts!!
      [(go (while true
             (>! c (rand))))
       (go (while true
             (<! c)))])))

So, your main thread will block until one of the channels in alts!! returns a value. Right now, it'll block forever, but this structure sets you up for more interesting things. For example, you could exit the application when the random value is above some threshold:

(defn -main
  [& args]
  (let [c (chan)]
    (alts!!
      [(go (while true
             (>! c (rand))))
       (go-loop [value (<! c)]
                (if (> value 0.8)
                  value ; return value from the go block
                  (recur (<! c))))])))

Or, go wild, timeout after a second:

(defn -main
  [& args]
  (let [c (chan)]
    (alts!!
      [(go (while true
             (>! c (rand))))
       (go (while true
             (<! c)))
       (timeout 1000)])))

The larger takeaway is that there's a good chance you're going to want to block your main thread to wait for those asynchronous go blocks to finish up their business.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top