<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hi all,<div><br></div><div>I'm having a couple of issues with timeouts in the web server. This is kind of related to the "dynamic-wind & kill-thread" thread.</div><div><br></div><div>I'm using a servlet and make-response/incremental to serve files from the file system to web users. I've attached simplified test code below (tested on PLT 4.1.4.1).</div><div><br></div><div>Three problems:</div><div><br></div><div> - large file downloads can take a long time, and can be killed by the web server's connection timeout (default 60 seconds);</div><div><br></div><div> - when the connection times out, the servlet thread is killed and leaves the file handle open permanently ("lsof -p <PID>").</div><div><br></div><div> - over time, the web server accrues open file handles until it hits the OS-imposed limit ("ulimit -n") and stops working properly (connecting to Postgres in my case).</div><div><br></div><div>I remember back in the day we had the same problem with files served using dispatch-files.ss. The solution there was to insert a call to adjust-connection-timeout! to increase the connection timeout for large files.</div><div><br></div><div>Here it's not so simple because make-response/incremental can do more than just serve static files.</div><div><br></div><div>I'd like to be able to call adjust-connection-timeout! from servlet code, but I don't think that feature is available from inside a servlet (no access to the connection object).</div><div><br></div><div>Cheers,</div><div><br></div><div>-- Dave</div><div><font class="Apple-style-span" face="Monaco"><br></font></div><div><font class="Apple-style-span" face="Monaco">===== test-server.ss =====</font></div><div><font class="Apple-style-span" face="Monaco"><br></font></div><div><div><font class="Apple-style-span" face="Monaco">#lang scheme/base</font></div><div><font class="Apple-style-span" face="Monaco"><br></font></div><div><font class="Apple-style-span" face="Monaco">(require scheme/runtime-path</font></div><div><font class="Apple-style-span" face="Monaco"> web-server/servlet-env</font></div><div><font class="Apple-style-span" face="Monaco"> web-server/http)</font></div><div><font class="Apple-style-span" face="Monaco"><br></font></div><div><font class="Apple-style-span" face="Monaco">; Plain text file of >60 bytes in length:</font></div><div><font class="Apple-style-span" face="Monaco">(define-runtime-path test-file "test-file.txt")</font></div><div><font class="Apple-style-span" face="Monaco"><br></font></div><div><font class="Apple-style-span" face="Monaco">; Serve the text file at an artificiually slow rage (1 byte/sec):</font></div><div><font class="Apple-style-span" face="Monaco">(define (make-test-response)</font></div><div><font class="Apple-style-span" face="Monaco"> (make-response/incremental</font></div><div><font class="Apple-style-span" face="Monaco"> 200</font></div><div><font class="Apple-style-span" face="Monaco"> "Okay"</font></div><div><font class="Apple-style-span" face="Monaco"> (current-seconds)</font></div><div><font class="Apple-style-span" face="Monaco"> #"text/plain"</font></div><div><font class="Apple-style-span" face="Monaco"> null</font></div><div><font class="Apple-style-span" face="Monaco"> (lambda (write)</font></div><div><font class="Apple-style-span" face="Monaco"> </font></div><div><font class="Apple-style-span" face="Monaco"> ; This is 4096 in my actual production code:</font></div><div><font class="Apple-style-span" face="Monaco"> (define BUFFER-SIZE 1)</font></div><div><font class="Apple-style-span" face="Monaco"> (define buffer (make-bytes BUFFER-SIZE))</font></div><div><font class="Apple-style-span" face="Monaco"> </font></div><div><font class="Apple-style-span" face="Monaco"> (call-with-input-file test-file</font></div><div><font class="Apple-style-span" face="Monaco"> (lambda (input)</font></div><div><font class="Apple-style-span" face="Monaco"> (let loop ([counter 0])</font></div><div><font class="Apple-style-span" face="Monaco"> </font></div><div><font class="Apple-style-span" face="Monaco"> (sleep 1)</font></div><div><font class="Apple-style-span" face="Monaco"> (printf "... ~as~n" counter)</font></div><div><font class="Apple-style-span" face="Monaco"> </font></div><div><font class="Apple-style-span" face="Monaco"> ; Send some data to the browser:</font></div><div><font class="Apple-style-span" face="Monaco"> (let ([num-read (read-bytes! buffer input)])</font></div><div><font class="Apple-style-span" face="Monaco"> (cond [(eof-object? num-read)</font></div><div><font class="Apple-style-span" face="Monaco"> (void)]</font></div><div><font class="Apple-style-span" face="Monaco"> [(= num-read BUFFER-SIZE)</font></div><div><font class="Apple-style-span" face="Monaco"> (write buffer)</font></div><div><font class="Apple-style-span" face="Monaco"> (loop (add1 counter))]</font></div><div><font class="Apple-style-span" face="Monaco"> [else</font></div><div><font class="Apple-style-span" face="Monaco"> (write (subbytes buffer 0 num-read))</font></div><div><font class="Apple-style-span" face="Monaco"> (loop (add1 counter))]))))))))</font></div><div><font class="Apple-style-span" face="Monaco"><br></font></div><div><font class="Apple-style-span" face="Monaco">; Main server loop:</font></div><div><font class="Apple-style-span" face="Monaco">(serve/servlet</font></div><div><font class="Apple-style-span" face="Monaco"> (lambda (request)</font></div><div><font class="Apple-style-span" face="Monaco"> (printf "Serving file.~n")</font></div><div><font class="Apple-style-span" face="Monaco"> (begin0 (make-test-response)</font></div><div><font class="Apple-style-span" face="Monaco"> (printf "Finished serving file.~n"))))</font></div><div><font class="Apple-style-span" face="Monaco"><br></font></div><div><font class="Apple-style-span" face="Monaco">===== end test-server.ss =====</font></div><div><font class="Apple-style-span" face="Monaco"><br></font></div><div><font class="Apple-style-span" face="Monaco">===== test-file.txt =====</font></div><div><font class="Apple-style-span" face="Monaco"><br></font></div><div><div><font class="Apple-style-span" face="Monaco">0123456789</font></div><div><font class="Apple-style-span" face="Monaco">0123456789</font></div><div><font class="Apple-style-span" face="Monaco">0123456789</font></div><div><font class="Apple-style-span" face="Monaco">0123456789</font></div><div><font class="Apple-style-span" face="Monaco">0123456789</font></div><div><font class="Apple-style-span" face="Monaco">0123456789</font></div><div><font class="Apple-style-span" face="Monaco">0123456789</font></div><div><font class="Apple-style-span" face="Monaco">0123456789</font></div><div><font class="Apple-style-span" face="Monaco">0123456789</font></div><div><font class="Apple-style-span" face="Monaco">0123456789</font></div><div><font class="Apple-style-span" face="Monaco"><br></font></div><div><font class="Apple-style-span" face="Monaco">===== end test-file.txt =====</font></div></div></div><div><br></div></body></html>