8 Troubleshooting and Tips
8.1 Why are my templates not updating on the server when I change the file on disk?
Templates are compiled into your application, so when you change them there is no connection between that change in the filesystem and the compiled bytecode that is already loaded in a running Web server process. For more discussion, see Why are my stateful servlets not updating on the server when I change the file on disk?.
8.2 Why are templates compiled into programs?
Since templates can include arbitrary Racket code, macros, etc and refer to arbitrary identifiers, include-template is really just an obscured require.
8.3 Why are my stateful servlets not updating on the server when I change the file on disk?
If you are using serve/servlet, it starts a Web server that directly references a closure that has no connection to some file on the disk.
If you are using the command-line tool, or configuration file, then by default, the server uses make-cached-url->servlet to load servlets from the disk. As it loads them, they are cached and the disk is not referred to for future requests. This ensures that there is a single namespace for each servlet, so that different instances can share resources, such as database connections, and communicate through the store. The default configuration of the server (meaning the dispatcher sequence used when you load a configuration file) provides a special URL to localhost that will reset the cache: "/conf/refresh-servlets".
If you want the server to reload your changed servlet code, then GET this URL and the server will reload the servlet on the next request. However, you may be surprised by what happens on the next request. For more discussion, see After refreshing my stateful servlet, old captured continuations don’t change or old global effects are gone. Why?.
8.4 After refreshing my stateful servlet, old captured continuations don’t change or old global effects are gone. Why?
Every load of your servlet is in a fresh namespace. When you refresh, a new namespace without the old effects is created. Old captured continuations refer to the original namespace and will never update. It is impossible, in general, to port a continuation from one namespace to another, because the code could be arbitrarily different.
8.5 How are stateless servlets different from stateful servlets vis a vis refreshing?
Continuations are serialized with a hash that ensures that any source code modifications makes all the old continuations incompatible for the same reason native continuations naturally are.
However, this hash only protects against changes in a single source file. Therefore if you modularize your application, then only continuations that refer to changed source files will be incompatible. For example, if you put all your templates in a single module, then it can change without invalidating old continuations.
8.6 What special considerations are there for security with the Web Server?
The biggest problem is that a naive usage of continuations will allow continuations to subvert authentication mechanisms. Typically, all that is necessary to execute a continuation is its URL. Thus, URLs must be as protected as the information in the continuation.
Consider if you link to a public site from a private continuation URL: the Referrer field in the new HTTP request will contain the private URL. Furthermore, if your HTTP traffic is in the clear, then these URLs can be easily poached.
One solution to this is to use a special cookie as an authenticator. This way, if a URL escapes, it will not be able to be used, unless the cookie is present. For advice about how to do this well, see Dos and Don’ts of Client Authentication on the Web from the MIT Cookie Eaters.
Note: It may be considered a great feature that URLs can be shared this way, because delegation is easily built into an application via URLs.
8.7 IE ignores my CSS or behaves strange in other ways
In quirks mode, IE does not parse your page as XML, in particular it will not recognize many instances of "empty tag shorthand", e.g. "<img src=’...’ />", whereas the Web Server uses xml to format XML, which uses empty tag shorthand by default. You can change the default with the empty-tag-shorthand parameter: (empty-tag-shorthand 'never).
8.8 How do I use templates “dynamically"?
.... |
(include-template (if logged-in? |
"user-info.html" |
"auth.html")) |
.... |
(define (main-page logged-in?) |
(include-template "site.html")) |
(define (main-page logged-in?) |
(define user-content |
(if logged-in? |
(include-template "user-info.html") |
(include-template "auth.html"))) |
(include-template "site.html")) |
.... |
user-content |
.... |
This allows you to do the same thing but is safer and more efficient: safer because there is no way to include templates that are not named by the programmer and more efficient because all the templates are compiled (and optimized) with the rest of the code.
If you insist on dynamicism, there is always eval.