racket/collects/web-server/timer.ss
Jay McCarthy a3c0f24fc9 Removing monolithic host-info
svn: r1362
2005-11-21 21:16:28 +00:00

96 lines
3.4 KiB
Scheme

(module timer mzscheme
(require "timer-structs.ss")
(require (lib "list.ss")
(lib "async-channel.ss"))
(provide timer?
start-timer reset-timer increment-timer
cancel-timer!
start-timer-manager)
(define timer-ch (make-async-channel))
; start-timer-manager : custodian -> void
; The timer manager thread
(define (start-timer-manager server-custodian)
(parameterize ([current-custodian server-custodian])
(thread
(lambda ()
(let loop ([timers null])
;; Wait for either...
(apply sync
;; ... a timer-request message ...
(handle-evt
timer-ch
(lambda (req)
;; represent a req as a (timer-list -> timer-list) function:
;; add/remove/change timer evet:
(loop (req timers))))
;; ... or a timer
(map (lambda (timer)
(handle-evt
(timer-evt timer)
(lambda (_)
;; execute timer
((timer-action timer))
(loop (remq timer timers)))))
timers))))))
(void))
;; Limitation on this add-timer: thunk cannot make timer
;; requests directly, because it's executed directly by
;; the timer-manager thread
;; add-timer : number (-> void) -> timer
(define (add-timer msecs thunk)
(let* ([now (current-inexact-milliseconds)]
[timer
(make-timer (alarm-evt (+ now msecs))
(+ now msecs)
thunk)])
(async-channel-put timer-ch
(lambda (timers)
(cons timer timers)))
timer))
; revise-timer! : timer msecs (-> void) -> timer
; revise the timer to ring msecs from now
(define (revise-timer! timer msecs thunk)
(let ([now (current-inexact-milliseconds)])
(async-channel-put
timer-ch
(lambda (timers)
(set-timer-evt! timer (alarm-evt (+ now msecs)))
(set-timer-expire-seconds! timer (+ now msecs))
(set-timer-action! timer thunk)
timers))))
(define (cancel-timer! timer)
(revise-timer! timer 0 void))
; start-timer : num (-> void) -> timer
; to make a timer that calls to-do after sec from make-timer's application
(define (start-timer secs to-do)
(add-timer (* 1000 secs) to-do))
; reset-timer : timer num -> void
; to cause timer to expire after sec from the adjust-msec-to-live's application
(define (reset-timer timer secs)
(revise-timer! timer (* 1000 secs) (timer-action timer)))
; increment-timer : timer num -> void
; add secs to the timer, rather than replace
(define (increment-timer timer secs)
(revise-timer! timer
(+ (- (timer-expire-seconds timer) (current-inexact-milliseconds))
(* 1000 secs))
(timer-action timer))))
; --- timeout plan
; start timeout on connection startup
; for POST requests increase the timeout proportionally when content-length is read
; adjust timeout in read-to-eof
; adjust timeout to starting timeout for next request with persistent connections
; adjust timeout proportionally when responding
; for servlet - make it a day until the output is produced