75 lines
3.2 KiB
Scheme
75 lines
3.2 KiB
Scheme
(module dispatch-server-unit (lib "a-unit.ss")
|
|
(require (lib "tcp-sig.ss" "net")
|
|
(lib "thread.ss")
|
|
(lib "contract.ss")
|
|
(lib "kw.ss"))
|
|
(require "web-server-structs.ss"
|
|
"connection-manager.ss"
|
|
"dispatch-server-sig.ss")
|
|
|
|
;; ****************************************
|
|
(import tcp^ (prefix config: dispatch-server-config^))
|
|
(export dispatch-server^)
|
|
|
|
;; serve: -> -> void
|
|
;; start the server and return a thunk to shut it down
|
|
(define (serve)
|
|
(define the-server-custodian (make-custodian))
|
|
(start-connection-manager the-server-custodian)
|
|
(parameterize ([current-custodian the-server-custodian]
|
|
[current-server-custodian the-server-custodian]
|
|
[current-thread-initial-stack-size 3])
|
|
(thread
|
|
(lambda ()
|
|
(run-server config:port
|
|
handle-connection
|
|
#f
|
|
(lambda (exn)
|
|
#f)
|
|
(lambda (p mw re)
|
|
(tcp-listen p config:max-waiting #t config:listen-ip))
|
|
tcp-close
|
|
tcp-accept
|
|
tcp-accept/enable-break))))
|
|
(lambda ()
|
|
(custodian-shutdown-all the-server-custodian)))
|
|
|
|
;; serve-ports : input-port output-port -> void
|
|
;; returns immediately, spawning a thread to handle
|
|
;; the connection
|
|
;; NOTE: (GregP) should allow the user to pass in a connection-custodian
|
|
(define (serve-ports ip op)
|
|
(define server-cust (make-custodian))
|
|
(start-connection-manager server-cust)
|
|
(parameterize ([current-custodian server-cust]
|
|
[current-server-custodian server-cust])
|
|
(define connection-cust (make-custodian))
|
|
(parameterize ([current-custodian connection-cust])
|
|
(thread
|
|
(lambda ()
|
|
(handle-connection ip op
|
|
(lambda (ip)
|
|
(values "127.0.0.1"
|
|
"127.0.0.1"))))))))
|
|
|
|
;; handle-connection : input-port output-port (input-port -> string string) -> void
|
|
;; returns immediately, spawning a thread to handle
|
|
(define/kw (handle-connection ip op
|
|
#:optional
|
|
[port-addresses tcp-addresses])
|
|
(define conn
|
|
(new-connection config:initial-connection-timeout
|
|
ip op (current-custodian) #f))
|
|
(with-handlers ([exn:fail:network?
|
|
(lambda (e)
|
|
(kill-connection! conn)
|
|
(raise e))])
|
|
(let connection-loop ()
|
|
(define-values (req close?) (config:read-request conn config:port port-addresses))
|
|
(adjust-connection-timeout! conn config:initial-connection-timeout)
|
|
(config:dispatch conn req)
|
|
(unless (connection-close? conn)
|
|
(set-connection-close?! conn close?))
|
|
(cond
|
|
[(connection-close? conn) (kill-connection! conn)]
|
|
[else (connection-loop)]))))) |