[racket] loop in stateless webserver acts different/weird

From: J G Cho (gcho at fundingmatters.com)
Date: Fri Aug 24 10:38:09 EDT 2012

So I have a module that runs fine in a web server. However when I
tried it in "stateless" server, it fails (msg: No instance for id: 1)
with a very short stacke trace. I run it by itself using (module+ main
...) then it runs but it does not work as intended (more on this
below).

So here are "toy" versions of what my module does which produces
similar behavior.

First, the version that works (uses the attached file as template):

#lang racket

(require web-server/servlet
         web-server/templates)

;; insert into UI Template and then dish out HTML
(define (form-template msg k-url output)
  (response/full
   200 #"Okay"
   (current-seconds) TEXT/HTML-MIME-TYPE
   empty
   (list (string->bytes/utf-8 (include-template "ui.html")))))

(define (all-ups xs)
  (if (null? xs)
      ""
      (string-append (string-upcase (car xs))
                     "<br/>"
                     (all-ups (cdr xs)))))

(define (main-loop txts parser helper)
  (local [(define (response-generator embed/url)
            (form-template
             (helper (reverse txts))
             (embed/url next-text-handler)
             (format "~a" (parser (reverse txts)))))

          (define (next-text-handler req)
            (main-loop (cons (extract-binding/single 'quote
(request-bindings req))
                             txts)
                       parser
                       helper))]

    (send/suspend/dispatch response-generator)))

(define (start initial-req)
  (main-loop '()
             (lambda (xs)
               (cond
                 [(null? xs) "To undo, just go back (short-cut
alt+left arrow)."]
                 [else (all-ups xs)]))
             (lambda (xs)
               (cond
                 [(null? xs) "Start:"]
                 [else (format "Input ~a: ready for more." (add1
(length xs)))]))))

(provide start)

(module+ main
  (require web-server/servlet-env)

  (serve/servlet start
                 #:quit? #t
                 #:listen-ip #f
                 #:log-file "debug.log" #:port 8082 #:launch-browser? #t
                 #:log-format 'parenthesized-default
                 #:servlet-path "/quotes"))

Here is the version that does not work (main difference is in module+ area):

#lang racket

(require web-server/servlet
         web-server/templates)

;; insert into UI Template and then dish out HTML
(define (form-template msg k-url output)
  (response/full
   200 #"Okay"
   (current-seconds) TEXT/HTML-MIME-TYPE
   empty
   (list (string->bytes/utf-8 (include-template "ui.html")))))

(define (all-ups xs)
  (if (null? xs)
      ""
      (string-append (string-upcase (car xs))
                     "<br/>"
                     (all-ups xs))))

(define (main-loop txts parser helper)
  (local [(define (response-generator embed/url)
            (form-template
             (helper (reverse txts))
             (embed/url next-text-handler)
             (format "~a" (parser (reverse txts)))))

          (define (next-text-handler req)
            (main-loop (cons (extract-binding/single 'quote
(request-bindings req))
                             txts)
                       parser
                       helper))]

    (send/suspend/dispatch response-generator)))

(define (start initial-req)
  (main-loop '()
             (lambda (xs)
               (cond
                 [(null? xs) "To undo, just go back (short-cut
alt+left arrow)."]
                 [else (all-ups xs)]))
             (lambda (xs)
               (cond
                 [(null? xs) "Start:"]
                 [else (format "Input ~a: ready for more." (add1
(length xs)))]))))

(provide start)

(module+ main
  (require web-server/servlet-env
           web-server/stuffers)

  (define stuffer
    (stuffer-chain
     serialize-stuffer
     (md5-stuffer (build-path (current-directory) "urls"))))

  (serve/servlet start
                 #:quit? #t
                 #:listen-ip #f
                 #:log-file "debug.log" #:port 8082 #:launch-browser? #t
                 #:log-format 'parenthesized-default
                 #:stateless? #t #:stuffer stuffer
                 #:servlet-path "/quotes"))

The failed version seems to have no memory (ie the previous inputs are
NOT available).

How can I fix this?

jGc
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20120824/4ea1ec0c/attachment-0001.html>

Posted on the users mailing list.