Updating docs

svn: r6471
This commit is contained in:
Jay McCarthy 2007-06-04 20:28:51 +00:00
parent 1d10ba83a6
commit 8a5e3c08ee
3 changed files with 93 additions and 27 deletions

View File

@ -221,7 +221,9 @@ that invokes a sequence of dispatchers until one applies.
@file{dispatchers/dispatch-servlets.ss} defines a dispatcher constructor
that runs servlets written in Scheme.
@; XXX Add default manager arg
@; XXX Remove config:instances
@; XXX Remove config:scripts
@; XXX Define make-servlet-namespace?
@defproc[(make [config:instances any/c]
[config:scripts (box/c cache-table?)]

View File

@ -87,9 +87,73 @@ Web Language. (See @secref["lang"].)
@; ------------------------------------------------------------
@section[#:tag "timeouts"]{Timeouts}
XXX
@file{managers/timeouts.ss} defines a manager constructor:
@defproc[(create-timeout-manager [instance-exp-handler expiration-handler?]
[instance-timeout number?]
[continuation-timeout number?])
manager?]{
Instances managed by this manager will be expired @scheme[instance-timeout]
seconds after the last time it is accessed. If an expired instance is
looked up, the @scheme[exn:fail:servlet-manager:no-instance] exception
is thrown with @scheme[instance-exp-handler] as the expiration handler.
Continuations managed by this manager will be expired @scheme[continuation-timeout]
seconds after the last time it is accessed. If an expired continuation is looked
up, the @scheme[exn:fail:servlet-manager:no-continuation] exception
is thrown with @scheme[instance-exp-handler] as the expiration handler, if
no expiration-handler was passed to @scheme[continuation-store!].
}
This manager has been found to be... problematic... in large-scale
deployments of the @file{web-server}.
@; ------------------------------------------------------------
@section[#:tag "lru"]{LRU}
XXX
@file{managers/lru.ss} defines a manager constructor:
@; XXX Rename time0 and time1
@; XXX Cite Continue
@defproc[(create-LRU-manager
[instance-expiration-handler expiration-handler?]
[time0 integer?]
[time1 integer?]
[collect? (-> boolean?)]
[#:initial-count initial-count integer? 1]
[#:inform-p inform-p (integer? . -> . void) (lambda _ (void))])
manager?]{
Instances managed by this manager will be expired if there are no
continuations associated with them, after the instance is unlocked.
If an expired instance is looked up, the
@scheme[exn:fail:servlet-manager:no-instance] exception
is thrown with @scheme[instance-exp-handler] as the expiration handler.
Continuations managed by this manager are given a "Life Count" of
@scheme[initial-count] initially. If an expired continuation is looked
up, the @scheme[exn:fail:servlet-manager:no-continuation] exception
is thrown with @scheme[instance-exp-handler] as the expiration handler, if
no expiration-handler was passed to @scheme[continuation-store!].
Every @scheme[time0] seconds @scheme[collect?] is called to determine
if the collection routine should be run. Every @scheme[time1] seconds
the collection routine is run.
Every time the collection routine runs, the "Life Count" of every
continuation is decremented by @scheme[1]. If a continuation's count
reaches @scheme[0], it is expired. The @scheme[inform-p] function
is called if any continuations are expired, with the number of
continuations expired.
}
The recommended use of this manager is to pass, as @scheme[collect?], a
function that checks the memory usage of the system, through
@scheme[current-memory-use]. Then, @scheme[time1] should be sufficiently
large compared to @scheme[time0]. This way, if the load on the server
spikes---as indicated by memory usage---the server will quickly expire
continuations, until the memory is back under control. If the load
stays low, it will still efficiently expire old continuations.
With Continue, we went from needing to restart the server a few times
a week and having many complaints under load, to not having these complaints
and not needing to restart the server for performance reasons.

View File

@ -125,30 +125,30 @@
next-instance-id))
; Collector
(define (collect)
(define (collect just-go?)
(define removed (box 0))
(when (collect?)
(hash-table-for-each
instances
(match-lambda*
[(list instance-id (struct instance (_ (struct k-table (next-id-fn htable)) use-count)))
(define empty? (box #t))
(hash-table-for-each
htable
(match-lambda*
[(list k-id (list s k eh count))
(if (zero? count)
(begin (set-box! removed (add1 (unbox removed)))
(hash-table-remove! htable k-id))
(begin (set-box! empty? #f)
(hash-table-put! htable k-id
(list s k eh (sub1 count)))))]))
(when (and (unbox empty?)
; XXX race condition
(zero? use-count))
(set-box! removed (add1 (unbox removed)))
(hash-table-remove! instances instance-id))])))
(unless (zero? (unbox removed))
(hash-table-for-each
instances
(match-lambda*
[(list instance-id (struct instance (_ (struct k-table (next-id-fn htable)) use-count)))
(define empty? (box #t))
(hash-table-for-each
htable
(match-lambda*
[(list k-id (list s k eh count))
(if (zero? count)
(begin (set-box! removed (add1 (unbox removed)))
(hash-table-remove! htable k-id))
(begin (set-box! empty? #f)
(hash-table-put! htable k-id
(list s k eh (sub1 count)))))]))
(when (and (unbox empty?)
; XXX race condition
(zero? use-count))
(set-box! removed (add1 (unbox removed)))
(hash-table-remove! instances instance-id))]))
(when (or just-go?
(not (zero? (unbox removed))))
(inform-p (unbox removed))
(collect-garbage)
(collect-garbage)))
@ -164,12 +164,12 @@
(alarm-evt msecs0)
(lambda _
(when (collect?)
(collect))
(collect #f))
(loop (seconds->msecs time0) msecs1)))
(handle-evt
(alarm-evt msecs1)
(lambda _
(collect)
(collect #t)
(loop msecs0 (seconds->msecs time1)))))))))
the-manager))