[plt-scheme] Cleanup on Servlet Timeout (Again)
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).
Matthew