Instaservlet
by Noel Welsh and Dave Gurnell
{noel, dave} at untyped
Instaservlet has been deprecated as of PLT 4.1.3. See the Deprecation notice for more information.
Instaservlet is an extremely fast way to run a web application in the PLT Web Server. You provide a function that accepts a request argument and returns a response. Instaservlet sets up the web server with sensible defaults, and runs your servlet in a wrapper that handles the details of instance and continuation expiry for you.
1 Deprecation notice
As of version 4.1.3, the PLT Web Server contains a quick-start procdure called serve/servlet. This procedure makes Instaservlet largely unnecessary: the package has consequently been deprecated and no future updates are planned.
Instaservlet users are advised to rewrite Instaweb applications using serve/servlet. This is made considerably easier using the Dispatch package from Untyped.
The next section describes how to migrate from Instaweb to serve/servlet if you are not using Dispatch; the following section describes the transition if you are using Dispatch.
1.1 Migrating to serve/servlet without using Dispatch
Instaservlet and serve/servlet use filesystem and servlet dispatcher procedures to handle requests. The dispatchers are chained together such that if one cannot handle a request the other is invoked. However, the order of dispatch is different:
Instaservlet calls filesystem dispatcher first. If no matching file is found, it calls the servlet dispatcher instead.
serve/servlet checks to see if the URL matches a user-specified #:servlet-regexp: if it does, the procedure calls the servlet dispatcher. If the URL doesn’t match, or if the servlet can’t handle the request, the procedure calls the filesystem dispatcher instead.
As of PLT 4.1.3, a servlet can signal that it cannot handle a request by calling the next-dispatcher procedure from the web-server/dispatchers/dispatch module.
To recreate Instaservlet-style behaviour using serve/servlet, use code like the following:
(require net/url |
web-server/http |
web-server/servlet-env |
web-server/dispatchers/dispatch) |
; Helper procedures -------------------------------- |
; url -> boolean |
(define (static-file-url? url) |
(let ([str (url->string url)]) |
(cond [(regexp-match #rx"^/stylesheets/" str) #t] |
[(regexp-match #rx"^/javascript/" str) #t] |
; and so on... |
[else #f]))) |
; request -> response |
(define (make-not-found-response request) |
; create a pretty 404 response...) |
; Servlet procedure -------------------------------- |
; request -> response |
(define (start request) |
(when (static-file-url? (request-uri request)) |
(next-dispatcher)) |
; continue handling the request...) |
; Main program body ------------------------------- |
(serve/servlet |
start |
; blank regexp passes all requests to the servlet: |
#:servlet-regexp #rx"" |
; initial URL to send to the browser: |
#:servlet-path "/" |
; default port is different: |
#:port 8765 |
; prettify 404 messages (optional): |
#:file-not-found-responder make-not-found-response) |
1.2 Migrating to serve/servlet using Dispatch
As of version 1.6, Dispatch interoperates with serve/servlet as you might expect. Rather than displaying a 404 page when none of the site URLs match, it calls next-dispatcher.
To recreate Instaservlet-style behaviour using serve/servlet and Dispatch, use code like the following:
(require web-server/http |
web-server/servlet-env |
web-server/dispatchers/dispatch |
(planet untyped/dispatch) |
(planet untyped/dispatch/response)) |
; Site definition ---------------------------------- |
; The site is normally written in a different module... |
; see the Dispatch documentation for more information. |
(define-site my-site |
([(url "/") home] |
; and so on...)) |
; Servlet procedure -------------------------------- |
; request -> response |
(define (start request) |
; Dispatch will handle the static file case: |
(dispatch my-site request)) |
; Main program body ------------------------------- |
(serve/servlet |
start |
; blank regexp passes all requests to the servlet: |
#:servlet-regexp #rx"" |
; initial URL to send to the browser: |
#:servlet-path "/" |
; default port is different: |
#:port 8765 |
; pretty 404 messages provided by Dispatch: |
#:file-not-found-responder make-not-found-response) |
2 Using Instaserlvet
Using Instaservlet is as simple as requiring the Instaservlet module and calling go! with your servlet function. For example, the following is a complete servlet that uses Instaservlet to handle all web-server configuration:
(require (planet untyped/instaservlet/instaservlet)) |
(define (servlet request) |
'(html (head (title "It's working!")) |
(body (h1 "Instaservlet is in the house!")))) |
(go! servlet) |
That is basically all there is to Instaservlet. By default the web-server listens on port 8765 to connections from the localhost only. You can change this by passing optional arguments to "go!". See the Instaservlet API for details.
3 Instaservlet API
(require (planet untyped/instaservlet/instaservlet)) |
The main function is go!:
Runs the given servlet in a web-server that has been setup (using Instaweb) with the given parameters (all of which are optional). By default the web server runs on port 8765 and listens only to connections from the localhost. Refer to the Instaweb documentation for more details.
3.1 How The Servlet Is Run
Instaweb takes care of some important servlet configuration details for you:
The servlet uses the web-server’s version 2 API
Memory is managed with the LRU manager, which is much more robust than the timeout manager. The memory limit is set to 64MB. Continuations start with 24 life points. Life points are deducted at the rate of one every 10 minutes, or one every 5 seconds when the memory limit is exceeded. Hence the maximum life time for a continuation is 4 hours, and the minimum is 2 minutes.
A default instance-expiration-handler is installed, so users see a sensible error message on continuation expiry.
These settings will be made customisable in future releases on Instaservlet.