Adding a barrier, making a better name, and support stateless in serve/servlet

svn: r12392
This commit is contained in:
Jay McCarthy 2008-11-11 22:24:44 +00:00
parent f96026edf1
commit 34c5db31ef
6 changed files with 55 additions and 29 deletions

View File

@ -268,7 +268,7 @@
(let* ([first-key (test-m06.1 '(dispatch-start start 'foo))] (let* ([first-key (test-m06.1 '(dispatch-start start 'foo))]
[second-key (test-m06.1 `(dispatch ,the-dispatch (list (deserialize (serialize ,first-key)) 1)))] [second-key (test-m06.1 `(dispatch ,the-dispatch (list (deserialize (serialize ,first-key)) 1)))]
[third-key (test-m06.1 `(dispatch ,the-dispatch (list (deserialize (serialize ,first-key)) -7)))]) [third-key (test-m06.1 `(dispatch ,the-dispatch (list (deserialize (serialize ,first-key)) -7)))])
(check = 3 (test-m06.1 `(abort/cc (lambda () (dispatch ,the-dispatch (list ,second-key 2)))))) (check = 3 (test-m06.1 `(call-with-web-prompt (lambda () (dispatch ,the-dispatch (list ,second-key 2))))))
(check = 4 (test-m06.1 `(dispatch ,the-dispatch (list ,second-key 3)))) (check = 4 (test-m06.1 `(dispatch ,the-dispatch (list ,second-key 3))))
(check-true (zero? (test-m06.1 `(dispatch ,the-dispatch (list ,second-key -1))))) (check-true (zero? (test-m06.1 `(dispatch ,the-dispatch (list ,second-key -1)))))
(check = -7 (test-m06.1 `(dispatch ,the-dispatch (list ,third-key 0)))) (check = -7 (test-m06.1 `(dispatch ,the-dispatch (list ,third-key 0))))
@ -295,7 +295,7 @@
(let* ([first-key (test-m06.2 '(dispatch-start start 'foo))] (let* ([first-key (test-m06.2 '(dispatch-start start 'foo))]
[second-key (test-m06.2 `(dispatch ,the-dispatch (list (deserialize (serialize ,first-key)) 1)))] [second-key (test-m06.2 `(dispatch ,the-dispatch (list (deserialize (serialize ,first-key)) 1)))]
[third-key (test-m06.2 `(dispatch ,the-dispatch (list (deserialize (serialize ,first-key)) -7)))]) [third-key (test-m06.2 `(dispatch ,the-dispatch (list (deserialize (serialize ,first-key)) -7)))])
(check = 3 (test-m06.2 `(abort/cc (lambda () (dispatch ,the-dispatch (list ,second-key 2)))))) (check = 3 (test-m06.2 `(call-with-web-prompt (lambda () (dispatch ,the-dispatch (list ,second-key 2))))))
(check = 4 (test-m06.2 `(dispatch ,the-dispatch (list ,second-key 3)))) (check = 4 (test-m06.2 `(dispatch ,the-dispatch (list ,second-key 3))))
(check-true (zero? (test-m06.2 `(dispatch ,the-dispatch (list ,second-key -1))))) (check-true (zero? (test-m06.2 `(dispatch ,the-dispatch (list ,second-key -1)))))
(check = -7 (test-m06.2 `(dispatch ,the-dispatch (list ,third-key 0)))) (check = -7 (test-m06.2 `(dispatch ,the-dispatch (list ,third-key 0))))

View File

@ -17,13 +17,13 @@
(test-case (test-case
"Easy" "Easy"
(check-equal? (abort/cc (check-equal? (call-with-web-prompt
(lambda () (current-saved-continuation-marks-and 'k1 'v1))) (lambda () (current-saved-continuation-marks-and 'k1 'v1)))
(make-immutable-hash (list (cons 'k1 'v1))))) (make-immutable-hash (list (cons 'k1 'v1)))))
(test-case (test-case
"Preserve" "Preserve"
(check-equal? (abort/cc (check-equal? (call-with-web-prompt
(lambda () (lambda ()
(with-continuation-mark the-save-cm-key (make-immutable-hash (list (cons 'k2 'v2))) (with-continuation-mark the-save-cm-key (make-immutable-hash (list (cons 'k2 'v2)))
(current-saved-continuation-marks-and 'k1 'v1)))) (current-saved-continuation-marks-and 'k1 'v1))))
@ -33,7 +33,7 @@
(test-case (test-case
"Update" "Update"
(check-equal? (abort/cc (check-equal? (call-with-web-prompt
(lambda () (lambda ()
(with-continuation-mark the-save-cm-key (with-continuation-mark the-save-cm-key
(make-immutable-hash (list (cons 'k2 'v2) (cons 'k1 'v3))) (make-immutable-hash (list (cons 'k2 'v2) (cons 'k1 'v3)))
@ -44,7 +44,7 @@
(test-case (test-case
"Double" "Double"
(check-equal? (abort/cc (check-equal? (call-with-web-prompt
(lambda () (lambda ()
(with-continuation-mark the-save-cm-key (with-continuation-mark the-save-cm-key
(make-immutable-hash (list (cons 'k3 'v1) (cons 'k4 'v0))) (make-immutable-hash (list (cons 'k3 'v1) (cons 'k4 'v0)))
@ -65,13 +65,13 @@
(test-case (test-case
"Easy" "Easy"
(check-equal? (abort/cc (check-equal? (call-with-web-prompt
(lambda () (activation-record-list))) (lambda () (activation-record-list)))
empty)) empty))
(test-case (test-case
"Single" "Single"
(check-equal? (abort/cc (check-equal? (call-with-web-prompt
(lambda () (lambda ()
(let/ec esc (let/ec esc
('f1 (with-continuation-mark the-cont-key + ('f1 (with-continuation-mark the-cont-key +
@ -80,7 +80,7 @@
(test-case (test-case
"Double" "Double"
(check-equal? (abort/cc (check-equal? (call-with-web-prompt
(lambda () (lambda ()
(let/ec esc (let/ec esc
('f1 (with-continuation-mark the-cont-key + ('f1 (with-continuation-mark the-cont-key +
@ -95,7 +95,7 @@
(check-exn (check-exn
exn? exn?
(lambda () (lambda ()
(abort/cc (call-with-web-prompt
(lambda () (lambda ()
(with-continuation-mark safe-call? #f (with-continuation-mark safe-call? #f
(activation-record-list)))))))) (activation-record-list))))))))
@ -109,7 +109,7 @@
(test-case (test-case
"Simple" "Simple"
(check-equal? (abort/cc (check-equal? (call-with-web-prompt
(lambda () (lambda ()
(abort (lambda () 42)))) (abort (lambda () 42))))
42))) 42)))
@ -145,7 +145,7 @@
[g (lambda (x) (+ x x))] [g (lambda (x) (+ x x))]
[esc-b (box #f)] [esc-b (box #f)]
[capture (lambda _ (activation-record-list))]) [capture (lambda _ (activation-record-list))])
(check-equal? (abort/cc (check-equal? (call-with-web-prompt
(lambda () (lambda ()
(let/ec esc (let/ec esc
(set-box! esc-b esc) (set-box! esc-b esc)
@ -159,7 +159,7 @@
"marks" "marks"
(let ([f (lambda (x) (* x x))] (let ([f (lambda (x) (* x x))]
[g (lambda (x) (+ x x))]) [g (lambda (x) (+ x x))])
(check-equal? (abort/cc (check-equal? (call-with-web-prompt
(lambda () (lambda ()
(let/ec esc (let/ec esc
(resume (list (vector f (make-immutable-hash (list (cons 3 4) (cons 1 2)))) (resume (list (vector f (make-immutable-hash (list (cons 3 4) (cons 1 2))))
@ -181,7 +181,7 @@
[g (lambda (x) (+ x x))] [g (lambda (x) (+ x x))]
[esc-b (box #f)] [esc-b (box #f)]
[capture (lambda _ (activation-record-list))]) [capture (lambda _ (activation-record-list))])
(check-equal? (abort/cc (check-equal? (call-with-web-prompt
(lambda () (lambda ()
(let/ec esc (let/ec esc
(set-box! esc-b esc) (set-box! esc-b esc)

View File

@ -221,9 +221,11 @@
(responders-servlet (responders-servlet
(request-uri req) (request-uri req)
exn))]) exn))])
(call-with-continuation-barrier
(lambda ()
(call-with-continuation-prompt (call-with-continuation-prompt
(lambda () (lambda ()
((servlet-handler the-servlet) req)) ((servlet-handler the-servlet) req))
servlet-prompt))))) servlet-prompt)))))))
(output-response conn response)))) (output-response conn response))))

View File

@ -87,7 +87,7 @@
[(vector f cms) [(vector f cms)
(with-continuation-marks/hash cms (lambda () (rebuild-cms fs thunk)))])])) (with-continuation-marks/hash cms (lambda () (rebuild-cms fs thunk)))])]))
(define (abort/cc thunk) (define (call-with-web-prompt thunk)
(call-with-continuation-prompt (call-with-continuation-prompt
thunk thunk
web-prompt)) web-prompt))
@ -132,7 +132,7 @@
;; dispatch-start: (request -> response) request -> reponse ;; dispatch-start: (request -> response) request -> reponse
;; pass the initial request to the starting interaction point ;; pass the initial request to the starting interaction point
(define (dispatch-start start req0) (define (dispatch-start start req0)
(abort/cc (call-with-web-prompt
(lambda () (lambda ()
(with-continuation-mark safe-call? '(#t start) (with-continuation-mark safe-call? '(#t start)
(start (start
@ -142,7 +142,7 @@
;; dispatch: (request -> (request -> response)) request -> response ;; dispatch: (request -> (request -> response)) request -> response
;; lookup the continuation for this request and invoke it ;; lookup the continuation for this request and invoke it
(define (dispatch decode-continuation req) (define (dispatch decode-continuation req)
(abort/cc (call-with-web-prompt
(lambda () (lambda ()
(cond (cond
[(decode-continuation req) [(decode-continuation req)
@ -166,7 +166,7 @@
(provide/contract (provide/contract
;; AUXILLIARIES ;; AUXILLIARIES
[abort ((-> any) . -> . any)] [abort ((-> any) . -> . any)]
[abort/cc ((-> any) . -> . any)] [call-with-web-prompt ((-> any) . -> . any)]
[resume (saved-context? any/c . -> . any)] [resume (saved-context? any/c . -> . any)]
[the-cont-key mark-key?] [the-cont-key mark-key?]
[the-save-cm-key mark-key?] [the-save-cm-key mark-key?]

View File

@ -56,6 +56,17 @@ Suppose you wanted to use a style-sheet (@filepath{style.css}) found on your Des
These files are served @emph{in addition} to those from the @scheme[#:server-root-path] @filepath{htdocs} directory. These files are served @emph{in addition} to those from the @scheme[#:server-root-path] @filepath{htdocs} directory.
Notice that you may pass any number of extra paths. Notice that you may pass any number of extra paths.
Suppose you would like to start a server for a stateless Web servlet @filepath{servlet.ss} that provides @schemeid[start]:
@schememod[
scheme
(require "servlet.ss"
web-server/servlet-env)
(serve/servlet start #:stateless? #t)
]
Note: If you put the call to @scheme[serve/servlet] in the module like normal, strange things will happen because of the way
the top-level interacts with continuations. (Read: Don't do it.)
@defproc[(serve/servlet [start (request? . -> . response?)] @defproc[(serve/servlet [start (request? . -> . response?)]
[#:launch-browser? launch-browser? boolean? #t] [#:launch-browser? launch-browser? boolean? #t]
[#:quit? quit? boolean? #t] [#:quit? quit? boolean? #t]
@ -65,6 +76,7 @@ Notice that you may pass any number of extra paths.
"/servlets/standalone.ss"] "/servlets/standalone.ss"]
[#:servlet-regexp servlet-regexp regexp? [#:servlet-regexp servlet-regexp regexp?
(regexp (format "^~a$" (regexp-quote servlet-path)))] (regexp (format "^~a$" (regexp-quote servlet-path)))]
[#:stateless? stateless? boolean? #f]
[#:manager manager manager? default-threshold-LRU-manager] [#:manager manager manager? default-threshold-LRU-manager]
[#:servlet-namespace servlet-namespace (listof module-path?) empty] [#:servlet-namespace servlet-namespace (listof module-path?) empty]
[#:server-root-path server-root-path path? default-server-root-path] [#:server-root-path server-root-path path? default-server-root-path]
@ -85,6 +97,8 @@ Notice that you may pass any number of extra paths.
If @scheme[quit?] is true, then the URL @filepath["/quit"] ends the server. If @scheme[quit?] is true, then the URL @filepath["/quit"] ends the server.
If @scheme[stateless?] is true, then the servlet is run as a stateless @schememodname[web-server] module.
Advanced users may need the following options: Advanced users may need the following options:
The server listens on @scheme[listen-ip] and port @scheme[port]. The server listens on @scheme[listen-ip] and port @scheme[port].

View File

@ -48,6 +48,7 @@
#:manager manager? #:manager manager?
#:servlet-namespace (listof module-path?) #:servlet-namespace (listof module-path?)
#:server-root-path path? #:server-root-path path?
#:stateless? boolean?
#:extra-files-paths (listof path?) #:extra-files-paths (listof path?)
#:servlets-root path? #:servlets-root path?
#:file-not-found-path path? #:file-not-found-path path?
@ -79,6 +80,8 @@
[servlet-path "/servlets/standalone.ss"] [servlet-path "/servlets/standalone.ss"]
#:servlet-regexp #:servlet-regexp
[servlet-regexp (regexp (format "^~a$" (regexp-quote servlet-path)))] [servlet-regexp (regexp (format "^~a$" (regexp-quote servlet-path)))]
#:stateless?
[stateless? #f]
#:servlet-namespace #:servlet-namespace
[servlet-namespace empty] [servlet-namespace empty]
@ -100,13 +103,7 @@
(make-make-servlet-namespace (make-make-servlet-namespace
#:to-be-copied-module-specs servlet-namespace)) #:to-be-copied-module-specs servlet-namespace))
(define sema (make-semaphore 0)) (define sema (make-semaphore 0))
(define servlet (define servlet-box (box #f))
(parameterize ([current-custodian (make-custodian)]
[current-namespace
(make-servlet-namespace
#:additional-specs
servlets:default-module-specs)])
(servlets:make-v2.servlet servlet-current-directory manager start)))
(define dispatcher (define dispatcher
(sequencer:make (sequencer:make
(if quit? (if quit?
@ -116,7 +113,20 @@
(lambda _ (next-dispatcher))) (lambda _ (next-dispatcher)))
(filter:make (filter:make
servlet-regexp servlet-regexp
(servlets:make (lambda (url) servlet))) (servlets:make
(lambda (url)
(or (unbox servlet-box)
(let ([servlet
(parameterize ([current-custodian (make-custodian)]
[current-namespace
(make-servlet-namespace
#:additional-specs
servlets:default-module-specs)])
(if stateless?
(servlets:make-stateless.servlet servlet-current-directory start)
(servlets:make-v2.servlet servlet-current-directory manager start)))])
(set-box! servlet-box servlet)
servlet)))))
(let-values ([(clear-cache! url->servlet) (let-values ([(clear-cache! url->servlet)
(servlets:make-cached-url->servlet (servlets:make-cached-url->servlet
(fsmap:filter-url->path (fsmap:filter-url->path