<commit_before>#lang scribble/doc
@(require "web-server.ss")

@title[#:tag "private" #:style 'toc]{Internal}
@(require (for-label scheme/tcp
                     web-server/dispatchers/dispatch
                     net/url
                     scheme/serialize
                     xml
                     net/tcp-sig))

The @web-server is a complicated piece of software and as a result,
defines a number of interesting and independently useful sub-components.
Some of these are documented here.

@local-table-of-contents[]


@; ------------------------------------------------------------
@section[#:tag "timer.ss"]{Timers}
@(require (for-label web-server/private/timer))

@defmodule[web-server/private/timer]{

@filepath{private/timer.ss} provides a functionality for running
procedures after a given amount of time, that may be extended.

@defstruct[timer ([evt evt?]
                  [expire-seconds number?]
                  [action (-> void)])]{
 @scheme[evt] is an @scheme[alarm-evt] that is ready at @scheme[expire-seconds].
 @scheme[action] should be called when this @scheme[evt] is ready.
}

@defproc[(start-timer-manager)
         void]{
 Handles the execution and management of timers.
}

@defproc[(start-timer [s number?]
                      [action (-> void)])
         timer?]{
 Registers a timer that runs @scheme[action] after @scheme[s] seconds.
}

@defproc[(reset-timer! [t timer?]
                       [s number?])
         void]{
 Changes @scheme[t] so that it will fire after @scheme[s] seconds.
}

@defproc[(increment-timer! [t timer?]
                           [s number?])
         void]{
 Changes @scheme[t] so that it will fire after @scheme[s] seconds from when
 it does now.
}

@defproc[(cancel-timer! [t timer?])
         void]{
 Cancels the firing of @scheme[t] ever and frees resources used by @scheme[t].
}

}

@; ------------------------------------------------------------
@section[#:tag "connection-manager.ss"]{Connection Manager}
@(require (for-label web-server/private/connection-manager))

@defmodule[web-server/private/connection-manager]{

@filepath{private/connection-manager.ss} provides functionality for managing pairs of
input and output ports. We have plans to allow a number of different strategies
for doing this.

@defstruct[connection
           ([timer timer?]
            [i-port input-port?] [o-port output-port?] [custodian custodian?]
            [close? boolean?])]{
 A connection is a pair of ports (@scheme[i-port] and @scheme[o-port]) that is
 ready to close after the current job if @scheme[close?] is @scheme[#t]. Resources
 associated with the connection should be allocated under @scheme[custodian].
 The connection will last until @scheme[timer] triggers.
}

@defproc[(start-connection-manager)
         void]{
 Runs the connection manager (now just the timer manager).
}

@defproc[(new-connection [timeout number?]
                         [i-port input-port?]
                         [o-port output-port?]
                         [cust custodian?]
                         [close? boolean?])
         connection?]{
 Constructs a connection with a timer with a trigger of @scheme[timeout] that calls
 @scheme[kill-connection!].
}

@defproc[(kill-connection! [c connection?])
         void]{
 Closes the ports associated with @scheme[c], kills the timer, and shuts down
 the custodian.
}

@defproc[(adjust-connection-timeout! [c connection?]
                                     [t number?])
         void]{
 Calls @scheme[reset-timer!] with the timer behind @scheme[c] with @scheme[t].
}
              
}

@; ------------------------------------------------------------
@section[#:tag "dispatch-server-unit.ss"]{Dispatching Server}
@(require (for-label web-server/private/dispatch-server-unit)
          (for-label web-server/private/dispatch-server-sig)
          (for-label web-server/web-server-sig))

The @web-server is just a configuration of a dispatching server.
This dispatching server component is useful on its own.

@subsection{Dispatching Server Signatures}

@defmodule[web-server/private/dispatch-server-sig]{

The @schememodname[web-server/private/dispatch-server-sig] library
provides two signatures.

@defsignature[dispatch-server^ ()]{

The @scheme[dispatch-server^] signature is an alias for
@scheme[web-server^].

 @defproc[(serve) (-> void)]{
  Runs the server and returns a procedure that shuts down the server.
 }

 @defproc[(serve-ports [ip input-port?]
                       [op output-port?])
          void]{
 Serves a single connection represented by the ports @scheme[ip] and
 @scheme[op].
 }
}

@defsignature[dispatch-server-config^ ()]{

 @defthing[port port?]{Specifies the port to serve on.}
 @defthing[listen-ip string?]{Passed to @scheme[tcp-accept].}
 @defthing[max-waiting integer?]{Passed to @scheme[tcp-accept].}
 @defthing[initial-connection-timeout integer?]{Specifies the initial timeout given to a connection.}
 @defproc[(read-request [c connection?]
                        [p port?]
                        [port-addresses (-> port? boolean?
                                            (or/c (values string? string?)
                                                  (values string? (integer-in 1 65535)
                                                          string? (integer-in 1 65535))))])
          any/c]{
  Defines the way the server reads requests off connections to be passed
  to @scheme[dispatch].
 }
 @defthing[dispatch dispatcher/c]{How to handle requests.}
}

}

@subsection{Dispatching Server Unit}

@defmodule[web-server/private/dispatch-server-unit]{

The @schememodname[web-server/private/dispatch-server-unit] module
provides the unit that actually implements a dispatching server.

@defthing[dispatch-server@ (unit/c (tcp^ dispatch-server-config^) 
                                   (dispatch-server^))]{
 Runs the dispatching server config in a very basic way, except that it uses
 @secref["connection-manager.ss"] to manage connections.
}

}

@; ------------------------------------------------------------
@section[#:tag "closure.ss"]{Serializable Closures}
@(require (for-label web-server/private/closure)
          (for-label web-server/private/define-closure))

@defmodule[web-server/private/closure]{

The defunctionalization process of the Web Language (see @secref["stateless-servlets"])
requires an explicit representation of closures that is serializable.
@filepath{private/closure.ss} is this representation. It provides:

@defproc[(make-closure-definition-syntax [tag syntax?]
                                         [fvars (listof identifier?)]
                                         [proc syntax?])
         syntax?]{
 Outputs a syntax object that defines a serializable structure,
 with @scheme[tag] as the tag, that represents a closure over
 @scheme[fvars], that acts a procedure and when invoked calls<commit_msg>Implementation note<commit_after>#lang scribble/doc
@(require "web-server.ss")

@title[#:tag "private" #:style 'toc]{Internal}
@(require (for-label scheme/tcp
                     web-server/dispatchers/dispatch
                     net/url
                     scheme/serialize
                     xml
                     net/tcp-sig))

The @web-server is a complicated piece of software and as a result,
defines a number of interesting and independently useful sub-components.
Some of these are documented here.

@local-table-of-contents[]


@; ------------------------------------------------------------
@section[#:tag "timer.ss"]{Timers}
@(require (for-label web-server/private/timer))

@defmodule[web-server/private/timer]{

@filepath{private/timer.ss} provides a functionality for running
procedures after a given amount of time, that may be extended.

@defstruct[timer ([evt evt?]
                  [expire-seconds number?]
                  [action (-> void)])]{
 @scheme[evt] is an @scheme[alarm-evt] that is ready at @scheme[expire-seconds].
 @scheme[action] should be called when this @scheme[evt] is ready.
}

@defproc[(start-timer-manager)
         void]{
 Handles the execution and management of timers.
}

@defproc[(start-timer [s number?]
                      [action (-> void)])
         timer?]{
 Registers a timer that runs @scheme[action] after @scheme[s] seconds.
}

@defproc[(reset-timer! [t timer?]
                       [s number?])
         void]{
 Changes @scheme[t] so that it will fire after @scheme[s] seconds.
}

@defproc[(increment-timer! [t timer?]
                           [s number?])
         void]{
 Changes @scheme[t] so that it will fire after @scheme[s] seconds from when
 it does now.
}

@defproc[(cancel-timer! [t timer?])
         void]{
 Cancels the firing of @scheme[t] ever and frees resources used by @scheme[t].
}

}

@; ------------------------------------------------------------
@section[#:tag "connection-manager.ss"]{Connection Manager}
@(require (for-label web-server/private/connection-manager))

@defmodule[web-server/private/connection-manager]{

@filepath{private/connection-manager.ss} provides functionality for managing pairs of
input and output ports. We have plans to allow a number of different strategies
for doing this.

@defstruct[connection
           ([timer timer?]
            [i-port input-port?] [o-port output-port?] [custodian custodian?]
            [close? boolean?])]{
 A connection is a pair of ports (@scheme[i-port] and @scheme[o-port]) that is
 ready to close after the current job if @scheme[close?] is @scheme[#t]. Resources
 associated with the connection should be allocated under @scheme[custodian].
 The connection will last until @scheme[timer] triggers.
}

@defproc[(start-connection-manager)
         void]{
 Runs the connection manager (now just the timer manager).
}

@defproc[(new-connection [timeout number?]
                         [i-port input-port?]
                         [o-port output-port?]
                         [cust custodian?]
                         [close? boolean?])
         connection?]{
 Constructs a connection with a timer with a trigger of @scheme[timeout] that calls
 @scheme[kill-connection!].
}

@defproc[(kill-connection! [c connection?])
         void]{
 Closes the ports associated with @scheme[c], kills the timer, and shuts down
 the custodian.
}

@defproc[(adjust-connection-timeout! [c connection?]
                                     [t number?])
         void]{
 Calls @scheme[reset-timer!] with the timer behind @scheme[c] with @scheme[t].
}
              
}

@; ------------------------------------------------------------
@section[#:tag "dispatch-server-unit.ss"]{Dispatching Server}
@(require (for-label web-server/private/dispatch-server-unit)
          (for-label web-server/private/dispatch-server-sig)
          (for-label web-server/web-server-sig))

The @web-server is just a configuration of a dispatching server.
This dispatching server component is useful on its own.

@subsection{Dispatching Server Signatures}

@defmodule[web-server/private/dispatch-server-sig]{

The @schememodname[web-server/private/dispatch-server-sig] library
provides two signatures.

@defsignature[dispatch-server^ ()]{

The @scheme[dispatch-server^] signature is an alias for
@scheme[web-server^].

 @defproc[(serve) (-> void)]{
  Runs the server and returns a procedure that shuts down the server.
 }

 @defproc[(serve-ports [ip input-port?]
                       [op output-port?])
          void]{
 Serves a single connection represented by the ports @scheme[ip] and
 @scheme[op].
 }
}

@defsignature[dispatch-server-config^ ()]{

 @defthing[port port?]{Specifies the port to serve on.}
 @defthing[listen-ip string?]{Passed to @scheme[tcp-accept].}
 @defthing[max-waiting integer?]{Passed to @scheme[tcp-accept].}
 @defthing[initial-connection-timeout integer?]{Specifies the initial timeout given to a connection.}
 @defproc[(read-request [c connection?]
                        [p port?]
                        [port-addresses (-> port? boolean?
                                            (or/c (values string? string?)
                                                  (values string? (integer-in 1 65535)
                                                          string? (integer-in 1 65535))))])
          any/c]{
  Defines the way the server reads requests off connections to be passed
  to @scheme[dispatch].
 }
 @defthing[dispatch dispatcher/c]{How to handle requests.}
}

}

@subsection{Dispatching Server Unit}

@defmodule[web-server/private/dispatch-server-unit]{

The @schememodname[web-server/private/dispatch-server-unit] module
provides the unit that actually implements a dispatching server.

@defthing[dispatch-server@ (unit/c (tcp^ dispatch-server-config^) 
                                   (dispatch-server^))]{
 Runs the dispatching server config in a very basic way, except that it uses
 @secref["connection-manager.ss"] to manage connections.
}

}

@subsection{Threads and Custodians}

The dispatching server runs in a dedicated thread. Every time a connection is initiated, a new thread is started to handle it.
Connection threads are created inside a dedicated custodian that is a child of the server's custodian. When the server is used to
provide servlets, each servlet also receives a new custodian that is a child of the server's custodian @bold{not} the connection
custodian.

@; ------------------------------------------------------------
@section[#:tag "closure.ss"]{Serializable Closures}
@(require (for-label web-server/private/closure)
          (for-label web-server/private/define-closure))

@defmodule[web-server/private/closure]{

The defunctionalization process of the Web Language (see @secref["stateless-servlets"])
requires an explicit representation of closures that is serializable.
@filepath{private/closure.ss} is this representation. It provides:

@defproc[(make-closure-definition-syntax [tag syntax?]
                                         [fvars (listof identifier?)]
                                         [proc syntax?])
         syntax?]{
 Outputs a syntax object that defines a serializable structure,
 with @scheme[tag] as the tag, that represents a closure over
 @scheme[fvars], that acts a procedure and when invoked calls
{'fraction_non_alphanumeric': 0.14290742696233721, 'fraction_numerical': 0.001689545934530095, 'mean_word_length': 2.46826171875, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3823859', 'n_tokens_mistral': 3883, 'n_tokens_neox': 3792, 'n_words': 1218}