I send a task to an agent, but can't see the output of any print statements I've put into the function. How do I trace code execution on agents?
EDIT: Turns out I do get the output in the console, but not in SLIME. The question now is, how to see the output in SLIME?
The key is to start swank from emacs as the inferior lisp process instead of calling lein swank from the shell. One way to do this is to use elein (the command is M-x elein-swank). Then you can either inspect the output in the inferior lisp buffer (which is called *elein-swank* in the example of using elein), or execute slime-redirect-inferior-output and have the output inline in the repl. Clojure.contrib.logging is a useful tool for sending log output.
You could wrap the calls in your repl in (with-out-str (def result (my-code))) to capture the output as a string. this way you can do it for just the code you're working on and you dont have to restart your repl to start getting your output.
Related
Let's say I want to call a C++ program from Clojure, like stockfish.
If I execute stockfish from the terminal, it stays open and interactive until the command is quit.
However, if I call from Clojure, it just calls it once and closes it.
I have used the programs macro of the me/conch package, like this:
user> (programs stockfish)
user> (stockfish "uci")
"Stockfish 030620 64 by T. Romstad ... \nuciok\n"
And the program stops. How can I get the process to stay open and to keep interacting until I tell it to quit?
This sort of problem has a canonical solution in the Unix expect tool, which has been replicated in, for example, Perl's Expect module. There might also be a Java version of Expect. If so, it might be a more direct solution.
About conch specifically, the README.md at https://github.com/Raynes/conch presents two ways of invoking a program. The first way is easy, but sends only one burst of standard input before closing the program, as you observed. The second way will be harder to work with, but you can send more input whenever you want by writing to the process' standard-input, and recover output whenever you want by reading from its standard-output. It's under the heading https://github.com/Raynes/conch#low-level-usage. It looks like a thin wrapper around the Java process API, which you might as well use directly.
How can you trap Ctrl-C in the Leiningen REPL?
set-break-handler! seems to have no effect:
user=> (set-break-handler! (fn [sig] (println "HERE!" sig)))
#object[clojure.repl.proxy$java.lang.Object$SignalHandler$d8c00ec7 0x22e61b57
"clojure.repl.proxy$java.lang.Object$SignalHandler$d8c00ec7#22e61b57"]
user=>
That funny character after the second prompt (if you can see it) is ASCII 3. That's what appeared when I hit Ctrl-C. It appears that Leiningen has disabled the connection between Ctrl-C and the SIGINT signal. (This is on a Linux system.) Leiningen treats the Ctrl-C as just another character. If I hit Enter, the Clojure compiler complains that it can't resolve the symbol . (Again, you might not be able to see it; Ctrl-C is not a printable glyph in most fonts.)
The reason I want this is so I can run some code that I'm experimenting with as an infinite loop, see what it does for a while, stop it, change it a bit, try it again, and so on. I don't actually want to set the INT-handler by calling set-break-handler directly at the REPL. I want to put it into my code so it cleans up its threads and kills its subprocess.
By the way, I thought I'd see if Leiningen is messing with my stty settings, so I typed this:
user=> (clojure.java.shell/sh "stty" "-a")
{:exit 1, :out "", :err "stty: standard input: Invalid argument\n"}
What?? stty -a works fine if I type it at the shell prompt. Is this a clue to the problem?
Whenever I call a clojure function that gets a users' console input using (read-line) through SLIME or a normal REPL, the function returns immediately. I've resorted to jar'ing up my project and running it to test but this obviously isn't quick or sustainable.
Is there some trick to getting console interaction through a REPL working or is it not possible? If not are there any good workarounds?
This will work now with swank-clojure 1.4.0-SNAPSHOT if you wrap the call to read-line in swank.core/with-read-line-support like this
(with-read-line-support (println "a line from Emacs:" (read-line))
https://github.com/technomancy/swank-clojure/commit/f4a1eebc4d34f2ff473c4e5350f889ec356f5168
Currently there doesn't seem to be any way of reading console input through swank-clojure; calling (read-line) simply returns nil in 1.4.0-SNAPSHOT and hangs in earlier versions. Installing 1.4.0 as a user-level leiningen plugin seems to be the best bet right now. At least the REPL will return to your control at some point.
How or in what way would I call out to my clojure code to process the tasks on a RabbitMQ queue?
Would I have to write a daemon or what?
I know java code takes a long time to start up initially, so I would hope there would be a way to write a long running process for my clojure code to be run against.
I'm totally lost as to what container clojure would run in e.g. would it be a daemon, if yes, how to write a clojure daemon?
Your question is a bit generic, so let me break it down:
You have a RabbitMQ queue and you want to consume messages from within Clojure
You want to run this message consumer as a standalone program
You want to run this program as a background task
From your question I understand that you've got the first part (consuming RabbitMQ messages in clojure) covered.
For the second part of your question, running a clojure program standalone:
You need to create a main function in your clojure code so that you can run it as a standalone program:
(defn -main [& args]
"your code")
For more on this, see the clojure website. If you are using Leiningen as a build tool, you should specify your main function in your project.clj file and then build an uberjar, e.g.
$ lein compile
$ lein uberjar
$ java -jar my-uber-jar.jar
The procedure to run your program as a background task is different for different operating systems. The simplest way to run something in the background is to add an ampersand after the command:
$ java -jar my-uber-jar.jar &
But your program will terminate when you close the terminal you typed this command in.
I wrote a blog post about clojure and rabbitMQ, hope it helps!
It covers adding messages to and getting them from queues.
http://www.learningclojure.com/2011/02/rabbitmq-clojure-hello-world.html
If you don't know how to make daemons (It's quite complicated, and I've never done it from clojure), but want a long running process, then a work around might be a screen session. Then you can run your program in a terminal, but still log out and leave it running.
As it happens, I also once wrote a getting started tutorial about screen. You can find it here:
http://johnsunixtips.blogspot.com/2010/12/most-basic-possible-screen-tutorial.h
I would just love a way to filter out the back-traces from the compilation process and see only the messages from the running of my program.
I'm currently using La Clojure for Intellij, though I also use slime/emacs.
If you're willing to drop back to the terminal to run, you can use mmcgrana's clj-backtrace to colorize and format the output of clojure's stacktraces.
A clj-like script that integrates clj-backtrace is available here.
Example:
example of clj-backtrace http://img.skitch.com/20091117-re5bqm6f5axg25mxpwcbcx53f8.png