[racket] loop in stateless webserver acts different/weird

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Fri Aug 24 22:21:25 EDT 2012

When you use

#lang web-server

You have to use

web-server/lang/web ---
http://docs.racket-lang.org/web-server/stateless.html#(part._lang/web)

rather than

web-server/servlet/web (which you are getting from web-server/servlet)

The problem is that your send/suspend/dispatch is the STATEFUL one,
not the STATELESS one and so there is no state instance available.

Jay

On Fri, Aug 24, 2012 at 8:38 AM, J G Cho <gcho at fundingmatters.com> wrote:
> 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
>
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users
>



-- 
Jay McCarthy <jay at cs.byu.edu>
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay

"The glory of God is Intelligence" - D&C 93

Posted on the users mailing list.