Index: api.scm ================================================================== --- api.scm +++ api.scm @@ -217,10 +217,28 @@ ;; (begin ;; #;(common:telemetry-log (conc "api-out:"(->string cmd)) ;; payload: `((params . ,params) ;; (ok-res . #f))) ;; (vector #t res)))))))) + +(define *api-threads* '()) +(define (api:register-thread th-in) + (set! *api-threads* (cons (cons th-in (current-seconds)) *api-threads*))) + +(define (api:unregister-thread th-in) + (set! *api-threads* (filter (lambda (thdat) + (not (eq? th-in (car thdat)))) + *api-threads*))) + +(define (api:remove-dead-or-terminated) + (set! *api-threads* (filter (lambda (thdat) + (not (member (thread-state (car thdat)) '(terminated dead)))) + *api-threads*))) + +(define (api:get-count-threads-alive) + (length *api-threads*)) + ;; indat is (cmd run-id params meta) ;; ;; WARNING: Do not print anything in the lambda of this function as it ;; reads/writes to current in/out port @@ -228,12 +246,14 @@ (define (api:tcp-dispatch-request-make-handler dbstruct) ;; cmd run-id params) (assert *toppath* "FATAL: api:tcp-dispatch-request-make-handler called but *toppath* not set.") (if (not *server-signature*) (set! *server-signature* (tt:mk-signature *toppath*))) (lambda (indat) + (api:register-thread (current-thread)) (let* (;; (indat (deserialize)) (newcount (+ *api-process-request-count* 1)) + (numthreads (api:get-count-threads-alive)) (delay-wait (if (> newcount 10) (- newcount 10) 0)) (normal-proc (lambda (cmd run-id params) (case cmd @@ -240,10 +260,16 @@ ((ping) *server-signature*) (else (api:dispatch-request dbstruct cmd run-id params)))))) (set! *api-process-request-count* newcount) (set! *db-last-access* (current-seconds)) + (if (not (eq? newcount numthreads)) + (begin + (api:remove-dead-or-terminated) + (let ((threads-now (api:get-count-threads-alive))) + (debug:print 0 *default-log-port* "WARNING: newcount="newcount", numthreads="numthreads", remaining="threads-now) + (set! newcount threads-now)))) (match indat ((cmd run-id params meta) (let* ((db-ok (let* ((dbfname (dbmod:run-id->dbfname run-id)) (ok (equal? dbfname (dbr:dbstruct-dbfname dbstruct)))) (case cmd @@ -264,11 +290,11 @@ (result (case status ((busy) (if (eq? cmd 'ping) (normal-proc cmd run-id params) ;; newcount must be greater than 5 for busy - (* 0.25 (- newcount 3)) ;; was 15 + (* 1 (- newcount 3)) ;; was 15 )) ;; (- newcount 29)) ;; call back in as many seconds ((loaded) ;; (if (eq? (rmt:transport-mode) 'tcp) ;; (thread-sleep! 0.5)) (normal-proc cmd run-id params)) @@ -278,10 +304,11 @@ ((ping) `((sstate . ,server-state))) (else `((wait . ,delay-wait))))) (payload (list status errmsg result meta))) (set! *api-process-request-count* (- *api-process-request-count* 1)) ;; (serialize payload) + (api:unregister-thread (current-thread)) payload)) (else (assert #f "FATAL: failed to deserialize indat "indat)))))) Index: dbfile.scm ================================================================== --- dbfile.scm +++ dbfile.scm @@ -1395,11 +1395,11 @@ (handle-exceptions exn #f ;; I don't really care why this failed (at least for now) (delete-file* fname))) -(define (dbfile:with-simple-file-lock fname proc #!key (expire-time 300)) +(define (dbfile:with-simple-file-lock fname proc #!key (expire-time 300)(run-anyway #f)) (let ((start-time (current-seconds)) (gotlock (dbfile:simple-file-lock-and-wait fname expire-time: expire-time)) (end-time (current-seconds)) ) (if gotlock @@ -1411,16 +1411,15 @@ (with-input-from-file fname (lambda () (dbfile:print-err (read-line))))) (dbfile:print-err "wait time = " (- end-time start-time)) (dbfile:print-err "ERROR: simple file lock could not get a lock for " fname " in " expire-time " seconds") - #f - ) - ) - ) -) - + (if run-anyway + (let ((res (proc))) + (dbfile:simple-file-release-lock fname) + res) + #f))))) (define *get-cache-stmth-mutex* (make-mutex)) (define (db:get-cache-stmth dbdat db stmt) (mutex-lock! *get-cache-stmth-mutex*) Index: dbmod.scm ================================================================== --- dbmod.scm +++ dbmod.scm @@ -175,11 +175,12 @@ (handler (sqlite3:make-busy-timeout 136000))) (sqlite3:set-busy-handler! db handler) (if (and dbexists write-access) (init-proc db)) - db)))) + db)) + run-anyway: #t)) (define *sync-in-progress* #f) ;; Open the cachedb db and the on-disk db ;; populate the cachedb db with data