On Tuesday, August 13, 2019 5:46 PM, George Neuner <gneun...@comcast.net> wrote:
> 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. Very cool solution. It works as expected. Thanks for sharing! That gives us closures which are thread-global. Cool! -- 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/O98QMFkv0sRRg3Dik8724-0tXMjSLk8s_OO8qAq36EsixyLDDE06W0QNBeGFXrFap6yRKG_y82eGdunArcrBLpCuB2NT3XaHIPflFMtWe10%3D%40protonmail.com.