Reputation: 686
I am puzzled by 2 things. One, the error message itself. And two, the fact that this code spins up so many threads. I was thinking it would spin up 2 or 3 threads in response to a single request, but when I run this on localhost and point my browser at it (just once) it spins up 40 threads. Admittedly, I was using Chrome, which sends 3 requests in the background, for various complicated reasons that Google defends as a "feature" (speed).
What does this error mean?
Exception in thread "Thread-39" java.lang.IllegalArgumentException: Key must be integer
at clojure.lang.APersistentVector.invoke(APersistentVector.java:250)
at serve_pages_from_memory.core$listen_and_respond$fn__51.invoke(core.clj:30)
at clojure.lang.AFn.run(AFn.java:24)
at java.lang.Thread.run(Thread.java:680)
I see similar errors have been discussed on StackOverflow before, but I don't see how they tie in to my problem:
I'm trying to build a simple app that serves a page. I do this mostly to test my own knowledge of Clojure. Here is most of the code:
(defn start-thread [f]
(doto (new Thread f) (.start)))
(defn serve-page [wrt]
(let [content-length (count page-string)]
(. wrt println "HTTP/1.1 200 OK")
(. wrt println "Content-Type: text/html; charset=UTF-8")
(. wrt println "Connection: Keep-Alive")
(. wrt println (str "Content-Length: " content-length))
(. wrt print "\r\n")
(. wrt print page-string)
(. wrt flush)
(. wrt close)))
(defn listen-and-respond [ss]
(let [client (. ss accept)]
(start-thread #([client]
(let [wrt (new PrintWriter (new BufferedWriter (new OutputStreamWriter (. client (getOutputStream)))))]
(serve-page wrt))))))
(defn create-server [port]
(let [ss (new ServerSocket port)]
(start-thread #(when-not (. ss (isClosed))
(try (listen-and-respond ss)
(catch SocketException e))
(recur)))
ss))
(defn -main [& args]
(println "Server is starting")
(let [port (Integer/parseInt (first args))]
(create-server port)))
The error seems to be complaining about this line:
(serve-page wrt))))))
But that is a function name and a PrintWriter object. The error message would suggest this was something about a map with keys. The error makes no sense.
Any suggestions?
Upvotes: 1
Views: 1587
Reputation: 91857
#([client]
(let [wrt (new PrintWriter (new BufferedWriter (new OutputStreamWriter (. client (getOutputStream)))))]
(serve-page wrt)))
is nonsense. If you want a lambda with named parameters, use the fn
form:
(fn [client]
(let [wrt (new PrintWriter (new BufferedWriter (new OutputStreamWriter (. client (getOutputStream)))))]
(serve-page wrt)))
Upvotes: 4