[racket] Closing down the web server

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Tue Oct 9 15:21:21 EDT 2012

On Mon, Oct 8, 2012 at 4:48 PM, Norman Gray <norman at astro.gla.ac.uk> wrote:
>
> 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.
>

I was talking about these functions:

http://docs.racket-lang.org/web-server-internal/web-server.html

But you can just do (thread () (serve/servlet ...))) and then kill
that thread or its custodian and it will do the same thing as
serve/servlet's /quit URL does.

>> 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.

You could do...

(define we (make-will-executor)
(will-register we db sql:close)
(define we-t (thread (lambda () (will-execute we))))

And when the db was unreachable (because its custodian/thread/etc was
killed), then the db would be closed. I believe you would have to
ensure that we-t is not within the control of the same custodian.

>> 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.
>

You should switch to using the built-in 'db' library if possible. Ryan
has fixed some errors and is otherwise doing a better job maintaining.

Regarding if you need to close it... I never close my databases :/ The
worst that could happen is a TXN gets rolled back when you restart
because it was happening as you were killing. If you are not worried
about that... Ctrl-C away!

Jay

> Or am I overcomplicating this, somehow? (not for the first time, regrettably…)
>
> Thanks for any pointers.
>
> Best wishes,
>
> Norman
>
>
> --
> Norman Gray  :  http://nxg.me.uk
> SUPA School of Physics and Astronomy, University of Glasgow, UK
>



-- 
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay

"The glory of God is Intelligence" - D&C 93


Posted on the users mailing list.