On Tue, Jun 5, 2012 at 7:50 PM, Sam Tobin-Hochstadt <sa...@ccs.neu.edu> wrote: > On Tue, Jun 5, 2012 at 9:38 PM, Jay McCarthy <jay.mccar...@gmail.com> wrote: >> There's no "cache" that could be cleared. >> >> The template code is included verbatim in the module that uses >> include-template _AT COMPILE TIME_; you would need to recompile to get >> the changes, at the very least. > > Jay, how convinced are you that this design is a good idea for the web > server? It makes the edit/compiled/debug cycle for web apps in Racket > significantly longer than in other languages that developers will > compare Racket with. Certainly, when I've developed Racket web apps, > I've wished that I didn't have to keep restarting the web server, > which I wouldn't in most other web frameworks. > > There may be other considerations that I'm not thinking of here, though.
In the case of templates, I see no need for anything else, given that Racket's composable features of moving compile-time to run-time work smoothly: #lang web-server/insta (require xml web-server/templates) (define i 0) (define-namespace-anchor here) (define (start req) (set! i (add1 i)) (response/xexpr (make-cdata #f #f (eval #'(include-template (file "/tmp/template.html")) (namespace-anchor->namespace here))))) Similarly, when you use serve/servlet you normally give it a particular closure that will be executed with the requests, but there's no reason you couldn't give it: (lambda (req) ((eval '(let () (local-require some-file) start)) req)) And then change both of these evals to something that was sensitive to filesystem modification... that would be a simple library to make if you wanted it that would be independent of the Web server. Compiling templates and closures in is the more flexible choice because going from a run-time to a compile-time would be much harder to manage. In general, however, it's not feasible to not restart the server. The core problem is that the continuations that are used in the server may have no meaning with the new code changes. For example, suppose you have... (define (start req) (define x (get-a-number)) (define y (get-a-number)) (+ x y)) and you accumulate a bunch of continuations at each of the two points (the definition of x and y) Then, you change the code so that it looks like this: (define (start req) (define local-value #f) (define x (get-a-number)) (set! local-value (* x 2)) (define y (get-a-number)) (+ x y local-value)) How are you going to convert a continuation from the old servlet at the point after x has been defined and you're waiting for y to one for the new servlet? Surely a magical converter could do the right thing and figure out what to set local-value to, but we all know that's just not feasible. Particularly given the underlying Racket infrastructure for manipulating continuations that have already been captured. That's not even to mention things where the new code is entirely unrelated to the old code. This is why when you use the stateless language, your continuations, which are not opaque, are stamped with an MD5 of your file so that they are revoked when you change the code. If you are okay with allowing the old continuations to continue existing and continue referring to the old code, then the server already supports this with /conf/refresh-servlets (in the default configuration). The old and new code can even communicate if you share some modules with the servlet-namespace argument. If you believe that you can convert from one continuation to another, then you could inspect the continuation and include information about it when you create URLs and have the "continuation not found or revoked" handler inspect those and reconstruct the continuation. Web cells and my URL-param library were designed for that purpose: http://planet.racket-lang.org/display.ss?package=url-param.plt&owner=jaymccarthy Overall, I don't see this as part of the "design" of the Web server. I think it is a natural consequence of (a) the way Racket works vis-a-vis opaque continuations, (b) caring about performance in the default case, and (c) Racket's strengths of making features compose so the Web server doesn't /need/ to do anything if you want more 'dynamic' behavior. Jay -- Jay McCarthy <j...@cs.byu.edu> Assistant Professor / Brigham Young University http://faculty.cs.byu.edu/~jay "The glory of God is Intelligence" - D&C 93 ____________________ Racket Users list: http://lists.racket-lang.org/users