This is probably more of a socket and network question than a Clojure question. I am learning Clojure and wanted to serve a web page through a simple app, mostly to teach myself how to put together such an app in Clojure. I grabbed the page on Wikipedia about mitochondria, and I compiled my app with that bundled in as a static resource. I figured I would serve that, it is biggest enough to offer a real test. On my local machine, everything works great. I can run:
lein compile
lein uberjar
java -jar serve-pages-from-memory-1.0-standalone.jar 9000
This gets it running on my Mac. If I then look at "localhost:9000" in a browser, I see the whole page. Everything seems to be working perfectly.
I have 2 servers in the Rackspace cloud, and I wanted to run this app on one and call it from another. So I upload the app to one server and then I ssh to the other server and I call it using wget. At this point problems start. wget has to call the page many times. The first several times it tries to call, it gets "Connection reset by peer". Only on the 6th try does wget get the whole document, successfully.
This is the output:
Resolving www.tailormadeanswers.com... 184.106.135.172
HTTP request sent, awaiting response... 200 OK
Length: 515592 (504K) [text/html]
Saving to: `tma.html'
89% [=========================================> ] 458,878 --.-K/s in 0.04s
2012-09-01 19:52:54 (11.1 MB/s) - Read error at byte 458878/515592 (Connection reset by peer). Retrying.
HTTP request sent, awaiting response... 200 OK
Length: 515592 (504K) [text/html]
Saving to: `tma.html'
84% [=======================================> ] 437,654 --.-K/s in 0.02s
2012-09-01 19:52:55 (18.5 MB/s) - Read error at byte 458878/515592 (Connection reset by peer). Retrying.
HTTP request sent, awaiting response... 200 OK
Length: 515592 (504K) [text/html]
Saving to: `tma.html'
98% [==============================================> ] 507,806 --.-K/s in 0.04s
2012-09-01 19:52:57 (12.1 MB/s) - Read error at byte 507806/515592 (Connection reset by peer). Retrying.
HTTP request sent, awaiting response... 200 OK
Length: 515592 (504K) [text/html]
Saving to: `tma.html'
95% [============================================> ] 490,254 --.-K/s in 0.05s
2012-09-01 19:53:00 (10.3 MB/s) - Read error at byte 507806/515592 (Connection reset by peer). Retrying.
HTTP request sent, awaiting response... 200 OK
Length: 515592 (504K) [text/html]
Saving to: `tma.html'
80% [=====================================> ] 413,966 --.-K/s in 0.04s
2012-09-01 19:53:04 (10.6 MB/s) - Read error at byte 507806/515592 (Connection reset by peer). Retrying.
HTTP request sent, awaiting response... 200 OK
Length: 515592 (504K) [text/html]
Saving to: `tma.html'
100%[===============================================>] 515,592 --.-K/s in 0.04s
2012-09-01 19:53:09 (12.5 MB/s) - `tma.html' saved [515592/515592]
I am confused by a number of things here. The document from Wikipedia is 500k, but wget seems to imply that it got 10.6 megs?
I am brainstorming a few things that might be wrong here: the response is too slow? some kind of multi-threading is needed to respond to the request in a timely manner?
Any suggestions?
This whole app is only 40 lines of code, and this is the important part:
(defn serve-page [output]
(let [content-length (count @parsed-page)]
(. output println "HTTP/1.1 200 OK")
(. output println "Content-Type: text/html; charset=UTF-8")
(. output println "Connection: close")
(. output println (str "Content-Length: " content-length))
(. output println "\r\n")
(. output println @parsed-page)
(. output flush)
(. output close)))
(defn parse-buffer [& everything-else]
(with-open []
(.toString (reduce #(.append %1 %2)
(StringBuffer.) (line-seq page-buffer)))))
(defn listen-and-respond [server-socket service]
(let [client (. server-socket accept)
output (PrintWriter. (. client getOutputStream)) ]
(service output)))
(defn run-server [port]
(let [server-socket (ServerSocket. port)]
(while (not (. server-socket isClosed))
(listen-and-respond server-socket serve-page))))
(defn -main [& args]
(let [port (Integer/parseInt (first args))]
(swap! parsed-page parse-buffer)
(println "Server is starting")
(println "port: " port)
(run-server port)))
Any suggestions about what might be wrong?