[plt-scheme] Cleanup on Servlet Timeout (Again)

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Thu Aug 28 05:23:01 EDT 2008

At Thu, 28 Aug 2008 00:09:36 -0400, "Henk Boom" wrote:
> First, the server will still be killed if the last process using it is
> terminated. This means that the sqlite transaction may be held open
> indefinitely, and the next server instantiated will not be able to
> access the database. 

That's true.

> I can see one easy way to fix this, which would
> be to call 'start-server' from the thread I use to start the web
> server initially, effectively anchoring the server thread. Is there a
> better way?

That sounds like the right solution to me.

> A separate issue is cleaning up sqlite resources allocated during
> reading/writing. I use prepared statements as a simple means to guard
> against SQL injection attacks, as they separate code from data in an
> SQL query. For example, to do a select query I actually have the
> following:
> (define (prepared-select query . params)
>   (let ((statement (prepare db query)))
>     (dynamic-wind
>       void
>       (lambda ()
>         (apply load-params statement params)
>         (step* statement))
>       (lambda () (finalize statement)))))
> The kicker is that if the statement is not finalized, the sqlite
> transaction will fail to close, so if a thread is terminated at the
> wrong time I could lose access to my database. I could let the server
> handle this whole process as well, but that doesn't sound like the
> right solution to the problem.

Why not?

More generally, you could run it in any thread that has the same
capability to run as the server thread --- perhaps another thread that
is created when the web server is started.

> Is there a way to make this function
> atomic, without manually putting it in a separate .c file and using
> the ffi?

Using the FFI, you could call scheme_start_atomic() and
scheme_end_atomic(), but I recommend the other approach.

A comment on your version of the code: A writer posts to `fail-s' even
after succeeding and posting to `done-s'. When both semaphores are
posted, there's no guarantee that the server will see `done-s' before
`fail-s', since it `sync's on both at the same time. That is, if both
are available before the server actually picks (perhaps even before the
server manages to call the `sync' function), then it might pick
`fail-s' even though `done-s' is available.

Also, you still need to use something like `reply' instead of
`channel-put' to accept a reader/writer, but I think you know about
that problem (and probably you're waiting to create a test that
demonstrates the problem before fixing it).


Posted on the users mailing list.