[racket] How to clean up a database connection in a program running in DrRacket?

From: Dmitry Pavlov (dpavlov at ipa.nw.ru)
Date: Fri Dec 26 12:13:40 EST 2014

Hello,

Let us say I put this program into DrRacket's Definitions window:

-----------------------------------------------------------------
#lang racket
(require db)

(define path "aaa.db")

(when (file-exists? path)
   (delete-directory/files path))

(define conn (sqlite3-connect #:database path #:mode 'create))
-----------------------------------------------------------------

and then press the "Run" button. After that, I play with conn
in the Interactions window. When I have played enough,
I press the "Run" button again. Here is what I get:

delete-file: cannot delete file
   path: [...]\aaa.db
   system error: Permission denied; errno=13

The reason is that I forgot to (disconnect conn) in the end.
(I get that only on Windows; Linux is OK with removing opened files).

How do I disconnect automatically? Putting the (disconnect conn)
into the Definitions window is not a solution, as I want to use
conn in the Interactions (also I want to be safe against the
"Stop" button pressed in the middle of the program before the
disconnect happens)

I tried to use a will executor:

-----------------------------------------------------------------
(define an-executor (make-will-executor))
(void
    (thread
     (lambda ()
       (let loop ()
         (will-execute an-executor)
         (loop)))))

(define (executor-proc v) (printf "I am now garbage\n") (disconnect v))
(will-register an-executor conn executor-proc)
-----------------------------------------------------------------

Surprisingly, it did not work for the database connection (while it
does work for other kinds of objects), and I have no idea why. It
does not work even with I call the GC explicitly:

-----------------------------------------------------------------
(set! conn #f)
(collect-garbage)
-----------------------------------------------------------------

Is it possible to make the will executor work?
Generally speaking, what is the recommended way to do this kind
of thing?


Best regards,

Dmitry


Posted on the users mailing list.