On 8/13/2019 2:24 PM, 'Wayne Harris' via Racket Users wrote:
With Chrome, I visited localhost:1111/main a first time and refreshed it.  (So 
I got a cache miss followed by a cache hit.)  With Firefox, I did the same and 
got a cache miss on the first request.  I expected a cache hit.

$ racket share.rkt
Now serving...
Your Web application is running at http://localhost:1111.
Stop this program at any time to terminate the Web Server.
database: cache miss
database: cache hit
database: cache miss
database: cache hit

Sorry ... I don't use parameters much and had to look up them up. The problem is that each browser request is handled by a separate thread, so the 2 browsers are using different threads and different instances of the parameter (which defaults to #f = miss).

TCP connections are (relatively) heavy weight, so browsers try to keep server connections open for subsequent requests.  When you refresh the page relatively quickly, it's likely you get an already existing handler thread back again.  If you wait a bit before refreshing the page - so the connection closes - you may see multiple misses even with just one browser.

The answer is don't use parameters for this purpose - use some other object such as a hash table or other thread-safe object that is defined in terms of with get/set accessors.  Something I have used for this in the past is:

;;
;;  mutual exclusion shared object
;;
(define-syntax getter/setter!
  (syntax-rules ()
    ((getter/setter!)
     ; -- start template

     (let* [
            (mtx (make-semaphore 1))
            (var null)
           ]
       (lambda x
         (call-with-semaphore mtx
           (lambda ()
             (cond
                 ([null? x] var)
                 ([pair? x] (set! var (car x)) var)
                 (else (error))
                 ))))
         )

     ; -- end template
     )))


You define shared objects as getter/setter!  and then use them similar to Racket's parameters, except that there is only one instance of each object shared by all its users.  E.g.,

If you were to add the macro above into "shared-model.rkt" and use it like:

    (define in-memory-database (getter/setter!))
    (in-memory-database #f)  ;; set initial value

then it all should act as you expect.  Since the macro actually creates a closure (which is a function), you can directly export the shared "object" from the module without needing other wrapper functions to use it.


Hope this helps,
George

--
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/2aee0d5f-df4c-9d11-a9c9-98b211fb9b21%40comcast.net.

Reply via email to