Index: dbfile.scm ================================================================== --- dbfile.scm +++ dbfile.scm @@ -78,11 +78,12 @@ ;; need to keep dbhandles and cached statements together (defstruct dbr:dbdat (dbfile #f) (dbh #f) (stmt-cache (make-hash-table)) - (read-only #f)) + (read-only #f) + (birth-sec (current-seconds))) (define *dbstruct-dbs* #f) (define *db-access-mutex* (make-mutex)) (define *no-sync-db* #f) (define *db-sync-in-progress* #f) @@ -239,13 +240,20 @@ (set! *dbfile:num-handles-in-use* (+ *dbfile:num-handles-in-use* 1)) (stack-pop! (dbr:subdb-dbstack subdb)))))) ;; return a previously opened db handle to the stack of available handles (define (dbfile:add-dbdat dbstruct run-id dbdat) - (let* ((subdb (dbfile:get-subdb dbstruct run-id))) - (set! *dbfile:num-handles-in-use* (- *dbfile:num-handles-in-use* 1)) - (stack-push! (dbr:subdb-dbstack subdb) dbdat))) + (let* ((subdb (dbfile:get-subdb dbstruct run-id)) + (age (- (current-seconds)(dbr:dbdat-birth-sec dbdat)))) + (if (> age 30) ;; just testing - discard and close after 30 sec + (begin + ;; (map sqlite3:finalize! (hash-table-values (dbr:dbdat-stmt-cache dbdat))) + ;; (sqlite3:finalize! (dbr:dbdat-dbh dbdat)) + (dbfile:print-err "INFO: Discarded dbdat over 30 sec old ("age"s)")) + (begin + (set! *dbfile:num-handles-in-use* (- *dbfile:num-handles-in-use* 1)) + (stack-push! (dbr:subdb-dbstack subdb) dbdat))))) ;; set up a subdb ;; (define (dbfile:init-subdb dbstruct run-id init-proc) (let* ((dbname (dbfile:run-id->dbname run-id)) @@ -495,19 +503,24 @@ (dbfile:print-err "INFO: forcing journal rollup "busy-file) (dbfile:brute-force-salvage-db fname))) (dbfile:cautious-open-database fname init-proc (- tries-left 1))) (let* ((db-exists (file-exists? fname)) (result (condition-case - (let* ((nosyncdb *no-sync-db*) - (lockname (conc fname ".lock")) + (let* ((is-no-sync (substring-index "no-sync.db" fname)) + (nosyncdb *no-sync-db*) + (lockname (conc fname ".lock")) (db (begin (dbfile:simple-file-lock-and-wait lockname expire-time: 5) - (if nosyncdb (db:no-sync-get-lock nosyncdb fname)) + (if (and (not is-no-sync) + nosyncdb) + (db:no-sync-get-lock nosyncdb fname)) (sqlite3:open-database fname)))) (if (and init-proc (not db-exists)) (init-proc db)) - (if nosyncdb (db:no-sync-del! nosyncdb fname)) + (if (and (not is-no-sync) + nosyncdb) + (db:no-sync-del! nosyncdb fname)) (dbfile:simple-file-release-lock lockname) db) (exn (io-error) (dbfile:print-err exn "ERROR: i/o error with " fname ". Check permissions, disk space etc. and try again.") (retry)) @@ -639,17 +652,18 @@ (exn (io-error) (dbfile:print-err "ERROR: i/o error with no-sync db. Check permissions, disk space etc. and try again.")) (exn (corrupt) (dbfile:print-err "ERROR: database no-sync db is corrupt. Repair it to proceed.")) (exn (busy) (dbfile:print-err "ERROR: database no-sync db is locked. Try copying to another location, remove original and copy back.")) (exn (permission)(dbfile:print-err "ERROR: database no-sync db has some permissions problem.")) - (exn (done) + (exn () ;; (status done) ;; I don't know how to detect status done but no data! (let ((lock-time (current-seconds))) ;; (debug:print-info 2 *default-log-port* "db:no-sync-get-lock keyname=" keyname ", lock-time=" lock-time ", exn=" exn) (sqlite3:execute db "INSERT OR REPLACE INTO no_sync_metadat (var,val) VALUES(?,?);" keyname lock-time) `(#t . ,lock-time))) - (exn () - (dbfile:print-err "ERROR: Unknown error with database no-sync db message: exn="(condition->list exn)", \n" ((condition-property-accessor 'exn 'message) exn)) + #;(exn () + (dbfile:print-err "ERROR: Unknown error with database no-sync db message: exn="(condition->list exn)", \n" + ((condition-property-accessor 'exn 'message) exn)) `(#f . ,(current-seconds))))))) (define (db:no-sync-get-lock-timeout db keyname timeout) (let* ((lockdat (db:no-sync-get-lock db keyname))) (match lockdat