On Dec 18, 10:10 pm, Chouser <chou...@gmail.com> wrote:
> On Thu, Dec 18, 2008 at 3:07 PM, Stephan Mühlstrasser
>
> <stephan.muehlstras...@web.de> wrote:
>
> > The following is my attempt to start a sub-process and to pass through
> > stdout and stderr.  The shell command prints out 1000 lines "hello"
> > and a final "command finished". The problem is that nothing is printed
> > by the Clojure program. If I increase the number of lines for example
> > to 2000 (change "head -1000" to "head -2000"), I see a lot of output,
> > but it is cut off somewhere in the middle and the final "command
> > finished" does never appear.
>
> This is just a buffering/flushing problem.  Try adding
> (.flush ostream) after your (.println ...)

Thanks, that was it! I put the flush in the else clause in copy, so it
flushes once at the end.

> > Is this use of agents incorrect?
>
> Since the action you're sending could block on IO, you should use
> 'send-off' instead of 'send'.  The difference is that the pool of
> threads used by 'send' doesn't grow with demand, so too many blocking
> threads could cause new 'send' calls to queue up unnecessarily.

Ah, I believe I finally understand the difference between send and
send-off. To describe it in my own words, send-off creates a new
thread each time, while send schedules to a thread in a thread pool.

So this is the complete example again which now does work as expected:

(use 'clojure.contrib.duck-streams)

(defn copy
    [istream ostream]
    (println "copy" istream ostream)
    (loop [line (.readLine istream)]
        (if line
            (do
                (.println ostream line)
                (recur (.readLine istream)))
            (.flush ostream))))

(let [pb (new ProcessBuilder ["sh" "-c" "yes hello | head -1000; echo
command finished"])
        proc (.start pb)
        stdout (reader (.getInputStream proc))
        stderr (reader (.getErrorStream proc))
        stdout-agent (agent stdout)
        stderr-agent (agent stderr)]
    (send-off stdout-agent copy (writer *out*))
    (send-off stderr-agent copy (writer *err*))
    (await stdout-agent stderr-agent)
    (.waitFor proc)
    (shutdown-agents)
    (println "done"))

Thanks
Stephan
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to