[racket] Closing down the web server

From: Norman Gray (norman at astro.gla.ac.uk)
Date: Mon Oct 8 18:48:07 EDT 2012

Jay, hello.

On 8 Oct 2012, at 20:23, Jay McCarthy <jay.mccarthy at gmail.com> wrote:

> All the functions that start the Web server (such as serve) return a
> function that with close the server when called.

Thanks for this, but is that dependent on the version of Racket?  I did vaguely recall something like this mechanism, but when I look at <http://docs.racket-lang.org/web-server/run.html#(def._((lib._web-server/servlet-env..rkt)._serve/servlet))> (which is pointing to the v5.3 docs, I think), serve/servlet appears to return void, and the only other serve/* procedure in the index to that part is serve/dispatch, which also returns void.

Am I looking in the wrong place?

I see this shutdown procedure in <http://docs.racket-lang.org/more/index.html#(part._.Terminating_.Connections>, but that's in the context of a tutorial example.

> All that function does is start the server with a particular custodian
> and then kills that custodian when you call the function. Any
> resources that the server allocates would have their will executors
> run. (The custodian controls the resources... killing it will cause
> the will executor to run on the resources, unless the process is
> killed, in which case nothing is normally run.)

That makes sense, but I'm afraid I'm not seeing how I'd put my own function (which will close/tidyup a database connection) into the care of the current-custodian.  I'm guessing that there's a link between custodians and will-executors, but the Custodians section (13.7) doesn't mention wills, and the section on Wills and Executors (15.3) doesn't mention custodians.  13.7 doesn't seem to say how one would add something to a custodian; and 15.3, although it suggests I should have a thread waiting on will-execute, doesn't seem to guarantee that a will procedure is ever definitely ready, for example when a web-server-closer procedure is called to terminate a custodian.

The only thing I can think of is the following.  Immediately after opening the database, I evaluate (db is the db connection):

(thread (λ ()
                 (let ((box (sync (make-custodian-box (current-custodian) db))))
                   (eprintf "Custodian box: ~s [~s]~%" box (custodian-box? box))
                   (sql:close (custodian-box-value box))
                   (eprintf "CLOSED!~%"))))

When I Ctrl-C the server, however, I see the "Web Server stopped." which comes from serve/launch/wait and its handler for exn:break? (yes?), but no messages from this thread, even though the custodian-box should become ready when the there-current custodian (which is surely one of those managed by the server's custodian) is shut down.

I'm guessing that I'm missing something, and in particular that there's some document I'm missing.  I'd love to RTFM, but I can't find which FM I should be R-ing.

> I don't have any Web apps that are started by anything other than a
> shell, so I always just Ctrl-C to quit.

That's my situation, too.  The server is started from a shell, but it opens a database connection (in fact using (planet "sqlite.rkt" ("jaymccarthy" "sqlite.plt" 5 1)), for which many thanks!), and I feel sure I should be carefully calling (close db) at some point.  I haven't been doing so, so far, and nothing's broken, but I don't write to the database very often so I guess I've just got away with it up to now.

Or am I overcomplicating this, somehow? (not for the first time, regrettably…)

Thanks for any pointers.

Best wishes,


Norman Gray  :  http://nxg.me.uk
SUPA School of Physics and Astronomy, University of Glasgow, UK

Posted on the users mailing list.