+ longer instance lifetime

+ GET-INSTANCES returns all instances as an alist
+ let SEND/SUSPEND terminate correctly if instance has died in the meanwhile
  (may happen while administrating servlets)
This commit is contained in:
interp 2002-10-01 12:08:42 +00:00
parent 3e9486573a
commit 1ac0705aae
1 changed files with 50 additions and 28 deletions

View File

@ -21,6 +21,10 @@
(value #f) (value #f)
(new-memo #f)) (new-memo #f))
;; caller must do locking stuff
(define (memo-killed! memo)
(set-memo:message memo 'killed))
(define-record-type session :session (define-record-type session :session
(make-session instance-id return-continuation) (make-session instance-id return-continuation)
session? session?
@ -31,7 +35,7 @@
(define-record options (define-record options
(cache-plugins? #t) (cache-plugins? #t)
(instance-lifetime 60)) ; in seconds (instance-lifetime 600)) ; in seconds
(define *options* (make-options)) (define *options* (make-options))
;(define *options-lock* (make-lock)) ; currently unused ;(define *options-lock* (make-lock)) ; currently unused
@ -47,7 +51,8 @@
(lambda () (lambda ()
(random-integer 1073741824)))) ; I hope, 1+ billion is enough.... (random-integer 1073741824)))) ; I hope, 1+ billion is enough....
(define (servlet-handler servlet-path) ;; servlet-prefix gives virtual prefixed path to servlets
(define (servlet-handler servlet-path servlet-prefix)
(lambda (path req) (lambda (path req)
(if (pair? path) ; need at least one element (if (pair? path) ; need at least one element
(let ((request-method (request:method req)) (let ((request-method (request:method req))
@ -69,9 +74,16 @@
((or (string=? request-method "GET") ((or (string=? request-method "GET")
; (string=? request-method "POST")) ; do this at later time ; (string=? request-method "POST")) ; do this at later time
) )
(let ((response
(if (resume-url? path-string) (if (resume-url? path-string)
(resume-url path-string servlet-path req) (resume-url path-string servlet-path req)
(launch-new-instance path-string servlet-path req))) (launch-new-instance path-string servlet-path req))))
(if (redirect-body? (response-body response))
;; prefix with servlet-path
(make-redirect-response
(string-join (file-name-as-directory servlet-prefix)
(redirect-body-location (response-body response))))
response)))
(else (else
(make-http-error-response http-status/method-not-allowed req (make-http-error-response http-status/method-not-allowed req
request-method)))) request-method))))
@ -117,7 +129,7 @@
(lambda () (lambda ()
(let loop ((time-to-die time-to-die) (let loop ((time-to-die time-to-die)
(memo memo)) (memo memo))
(debug "instance-surveillance[~s]: going to sleep until ~a~%" (debug "instance-surveillance[~s]: going to sleep until ~a"
instance-id (format-date "~c" (date time-to-die))) instance-id (format-date "~c" (date time-to-die)))
(let ((seconds-to-sleep (- time-to-die (time)))) (let ((seconds-to-sleep (- time-to-die (time))))
(if (positive? seconds-to-sleep) (if (positive? seconds-to-sleep)
@ -125,22 +137,22 @@
;; check state of the world ;; check state of the world
(case (memo:message memo) (case (memo:message memo)
((killed) ; too late ((killed) ; too late
(debug "instance-surveillance[~s]: instance already killed, dieing~%" (debug "instance-surveillance[~s]: instance already killed, dieing"
instance-id) instance-id)
) )
((adjust-timeout) ; new timeout ((adjust-timeout) ; new timeout
(debug "instance-surveillance[~s]: adjusting timeout~%" instance-id) (debug "instance-surveillance[~s]: adjusting timeout" instance-id)
(loop (memo:value memo) (loop (memo:value memo)
(memo:new-memo memo))) (memo:new-memo memo)))
((kill) ; kill instance ((kill) ; kill instance
(debug "instance-surveillance[~s]: killing~%" (debug "instance-surveillance[~s]: killing"
instance-id) instance-id)
(obtain-lock *instance-table-lock*) (obtain-lock *instance-table-lock*)
(table-set! *instance-table* instance-id #f) (table-set! *instance-table* instance-id #f)
(release-lock *instance-table-lock*)) (release-lock *instance-table-lock*))
(else (else
(format (current-error-port) (format (current-error-port)
"instance-surveillance[~s]: unknown message ~s; dieing~%" "instance-surveillance[~s]: unknown message ~s; dieing"
instance-id (memo:message memo))))))) instance-id (memo:message memo)))))))
@ -193,6 +205,9 @@
(shift return (shift return
(let* ((instance-id (session-instance-id)) (let* ((instance-id (session-instance-id))
(instance (instance-lookup instance-id))) (instance (instance-lookup instance-id)))
;; the session might be deleted in the meanwhile
(if instance
(begin
(instance-adjust-timeout! instance-id) (instance-adjust-timeout! instance-id)
(let ((continuations-table (instance-continuation-table instance)) (let ((continuations-table (instance-continuation-table instance))
(continuation-table-lock (instance-continuation-table-lock instance)) (continuation-table-lock (instance-continuation-table-lock instance))
@ -205,7 +220,9 @@
instance-id instance-id
continuation-counter continuation-counter
continuation-id))) continuation-id)))
(response-maker new-url))))))) (response-maker new-url)))))
(make-http-error-response http-status/not-found #f
"The URL refers to a servlet, whose instance is no longer alive.")))))
(define (send/finish response) (define (send/finish response)
(instance-delete! (session-instance-id)) (instance-delete! (session-instance-id))
@ -267,9 +284,15 @@
(set! *instance-table* (make-integer-table)) (set! *instance-table* (make-integer-table))
(release-lock *instance-table*)))) (release-lock *instance-table*))))
;; caller must do locking stuff (define (get-instances)
(define (memo-killed! memo) (obtain-lock *instance-table-lock*)
(set-memo:message memo 'killed)) (let ((instances '()))
(table-walk
(lambda (instance-id instance-entry)
(set! instances (cons (cons instance-id instance-entry) instances)))
*instance-table*)
(release-lock *instance-table-lock*)
instances))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -311,7 +334,6 @@
;; only now the lock may be released ;; only now the lock may be released
(release-lock *plugin-table-lock*))) (release-lock *plugin-table-lock*)))
plugin-structure)))))) plugin-structure))))))
(if (options:cache-plugins? *options*) (if (options:cache-plugins? *options*)
(begin (begin
;; The lock is only obtained and released, if plugins are ;; The lock is only obtained and released, if plugins are