Ok, I think I've got it, but just to make sure I'm not missing any
subtleties, or else for the benefit of posterity, here's the version with
thread cells.


In "common.rkt":

#lang racket

(provide my-val
         call-with-my-val)

(define cell:my-val
  (make-thread-cell #f #t))

(define (my-val)
  (thread-cell-ref cell:my-val))

(define (call-with-my-val new thunk)
  (let ([old (my-val)])
    (dynamic-wind (λ () (thread-cell-set! cell:my-val new))
                  thunk
                  (λ () (thread-cell-set! cell:my-val old)))))


In "servlet.rkt":

#lang web-server

(require "common.rkt")

(provide start)

(define (start req)
  (response/xexpr
   `(html (head (title "Example"))
          (body (p ,(format "~v" (my-val)))))))


In "run.rkt":

#lang racket

(require "common.rkt"
         "servlet.rkt"
         web-server/http
         web-server/servlet-dispatch)

(define ((wrap-dispatcher inner) connection request)
  (call-with-my-val (request-uri request)
                    (λ () (inner connection request))))

(serve/launch/wait (λ (quit-sema)
                     (wrap-dispatcher
                      (dispatch/servlet start
                                        #:stateless? #t)))
                   #:banner? #t)


Thanks so much!

Philip


-Philip

On Thu, Jun 22, 2017 at 9:31 AM, Jay McCarthy <jay.mccar...@gmail.com>
wrote:

> On Thu, Jun 22, 2017 at 10:21 AM, Philip McGrath
> <phi...@philipmcgrath.com> wrote:
> > I've come up with a (relatively) minimal example.
> >
> > In "common.rkt":
> >>
> >> #lang racket
> >> (provide my-param)
> >> (define my-param
> >>   (make-parameter #f))
> >
> >
> > In "servlet.rkt":
> >>
> >> #lang web-server
> >> (require "common.rkt")
> >> (provide start)
> >> (define (start req)
> >>   (response/xexpr
> >>    `(html (head (title "Example"))
> >>           (body (p ,(format "~v" (my-param)))))))
> >
> >
> > In "run.rkt":
> >>
> >> #lang racket
> >> (require "common.rkt"
> >>          "servlet.rkt"
> >>          web-server/http
> >>          web-server/servlet-dispatch)
> >> (define ((wrap-dispatcher inner) connection request)
> >>   (parameterize ([my-param (request-uri request)])
> >>     (inner connection request)))
> >> (serve/launch/wait (λ (quit-sema)
> >>                      (wrap-dispatcher
> >>                       (dispatch/servlet start
> >>                                         #:stateless? #t)))
> >>                    #:banner? #t)
> >
> >
> > If you visit a bunch of different URLs, the page will always show the
> first
> > URL you visited.
> >
> > From what you said, I'm guessing the problem is that "the stateless Web
> > language guarantees that the parameters will have values they had when
> the
> > servlet was initialized", which I was not aware of.
>
> Yup
>
> > I haven't worked with thread cells before, if that is indeed where I
> want to
> > store this data. One difference that immediately occurs to me is that the
> > value would not be propagated to any new child threads, right?
>
> If you want it propagated, then create the cell with #t for preserved?
>
> http://docs.racket-lang.org/reference/threadcells.html?q=
> thread-cell#%28def._%28%28quote._~23~25kernel%29._make-thread-cell%29%29
>
> > Thanks,
> > Philip
> >
> > -Philip
> >
> > On Thu, Jun 22, 2017 at 8:39 AM, Jay McCarthy <jay.mccar...@gmail.com>
> > wrote:
> >>
> >> Hi Philip,
> >>
> >> I think I'd have to see more code to really tell what the problem is,
> >> but here are some thoughts:
> >>
> >> - A continuation captures the values of parameters at the time it is
> >> captured. So, if your parameterize is outside of the dispatcher that
> >> calls the continuation, then the code inside the continuation will not
> >> see the parameter change. That's a pretty important feature of
> >> continuations.
> >>
> >> - Web parameters would work the same way as normal parameters and not
> help
> >> you.
> >>
> >> - The stateless Web language guarantees that the parameters will have
> >> values they had when the servlet was initialized.
> >>
> >> - I think that you may want to use a thread-cell as the storage place.
> >>
> >> Jay
> >>
> >>
> >> On Thu, Jun 22, 2017 at 3:56 AM, Philip McGrath
> >> <phi...@philipmcgrath.com> wrote:
> >> > I'm encountering some strange behavior when using parameters with my
> >> > (stateless) web servlets.
> >> >
> >> > I want to check the value of a cookie every time a request is made to
> my
> >> > server and make a Racket value derived from the cookie's value
> available
> >> > for
> >> > use within the servlet code. Since this value shouldn't be stored in
> the
> >> > continuation — it should be generated fresh for every request — it
> >> > seemed
> >> > like writing a dispatcher (in the sense of serve/launch/wait, not of
> >> > dispatch-rules) was the right place to do this. Since the servlet code
> >> > itself does not need to (and indeed should not) modify the value, I
> >> > thought
> >> > I could use a standard parameter to store the value. Essentially I
> have
> >> > a
> >> > function shaped like this:
> >> >
> >> > (define ((wrap-dispatcher inner) connection request)
> >> >   (parameterize ([my-param ...])
> >> >     (inner connection request)))
> >> >
> >> > where inner is a dispatcher produced by dispatch/servlet.
> >> >
> >> > All of the work being done by wrap-dispatcher seems to be happening
> >> > correctly (e.g. setting and reading the cookie), but within the
> servlet
> >> > itself, the parameter seems to get "stuck" on the first value
> installed
> >> > by
> >> > wrap-dispatcher after the server is launched (which is not the default
> >> > value
> >> > for the parameter).
> >> >
> >> > I'm not sure why this is happening. I understand that plain parameters
> >> > cannot be set within stateless servlets for serialization reasons
> (hence
> >> > the
> >> > existence of web-parameters), but I didn't think that impacted code
> that
> >> > merely accesses the value of a parameter.
> >> >
> >> > More urgently, I'm not sure how to fix it. Would making my-param a web
> >> > parameter solve the problem (without storing the value in the
> >> > continuation)?
> >> > Or is there some other method that should be used for this sort of
> >> > per-request work?
> >> >
> >> > Thanks,
> >> > Philip
> >> >
> >> > --
> >> > You received this message because you are subscribed to the Google
> >> > Groups
> >> > "Racket Users" group.
> >> > To unsubscribe from this group and stop receiving emails from it, send
> >> > an
> >> > email to racket-users+unsubscr...@googlegroups.com.
> >> > For more options, visit https://groups.google.com/d/optout.
> >>
> >>
> >>
> >> --
> >> -=[     Jay McCarthy               http://jeapostrophe.github.io    ]=-
> >> -=[ Associate Professor        PLT @ CS @ UMass Lowell     ]=-
> >> -=[ Moses 1:33: And worlds without number have I created; ]=-
> >
> >
>
>
>
> --
> -=[     Jay McCarthy               http://jeapostrophe.github.io    ]=-
> -=[ Associate Professor        PLT @ CS @ UMass Lowell     ]=-
> -=[ Moses 1:33: And worlds without number have I created; ]=-
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to