On Tuesday, August 13, 2019 2:17 PM, George Neuner <gneun...@comcast.net> wrote:

> On 8/13/2019 11:47 AM, 'Wayne Harris' via Racket Users wrote:
>
> > I'd like to save database results in memory because my database only
> > changes between long time intervals.  By building a minimum
> > application, I see my cache-strategy seems to work per servlet: by
> > opening a new browser, the first request yields a cache-miss.
> > Looking through the documentation, I got the idea that perhaps I
> > should serve/servlet using
> > #:servlet-namespace '("shared-model.rkt")
> > where shared-model.rkt is the module that talks to the database and
> > implements the caching-strategy.  But adding this keyword to
> > serve/servlet did not make any perceived difference.
> > What should I do to save results in memory across all requests?
>
> AFAIK #:servlet-namespace isn't necessary -  you can share data (via
> access functions) among different instances of request handlers just by
> requiring the modules (files) that define the common objects wherever
> you need them.

I think it's what I'm doing below --- I require shared-model.rkt and call

  (get-in-memory-results)

when I need it.

> If I'm not mistaken about the serve/servlet call in your code below, you
> are relying on the application to open the new browser window ...
> terminating and restarting the application each time.  That clears your
> "cache", guaranteeing that it misses the first time. You should set 
> #:launch-browser? #f  , start the application and connect to it from
> your browser with the URL http://localhost:1111.

The documentation doesn't say that #:launch-browser? would have this effect.  
Nevertheless, I tried it with #:launch-browser? #f, but the behavior was the 
same.

(define (main)
    (displayln "Now serving...")
    (serve/servlet dispatch
                   #:launch-browser? #f
                   #:stateless? #t
                   #:log-file (build-path "logs/httpd.log")
                   #:port 1111
                   #:listen-ip "127.0.0.1"
                   #:servlet-path "/"
                   #:servlet-regexp #rx""
                   #:extra-files-paths (list (build-path "pub/"))
                   #:server-root-path (build-path "/")
                   #:file-not-found-responder file-not-found))

A browser window didn't open.  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

> That said:
>
> What DBMS are you using? 

I'm using sqlite and in other applications I store lists on disk.  These are 
very small applications and it's useful not to depend on other software and 
libraries.

> [...] Server based DBMS like Oracle, Postgresql,
> MySQL, SQLServer, etc.  automatically cache query results in case the
> same query is run again.  If the server is well provisioned memory-wise,
> it can take a long time for a popular query to age out the cache.   If
> your application is co-resident (on the same machine) with the server,
> caching results yourself would be duplicating effort.

Thanks for the info!

> > --- server.rkt
> >
> > ---------------
> >
> > #lang racket/base
> > (require
> > web-server/servlet
> > web-server/servlet-env
> > (prefix-in model: "shared-model.rkt"))
> > (define-values (dispatch url)
> >   (dispatch-rules
> >    (("main") db->response)
> >    (("update" (string-arg)) update->response)))
> > (define (update->response r s)
> >   (define str (model:in-memory-db-set-and-get s))
> >   (displayln str)
> >   (string->response str))
> > (define (db->response r)
> >   (string->response (model:get-in-memory-results)))
> > ;; no more api endpoints ==/==
> > (define (string->response s)
> >   (response/full 200 #"Okay" (current-seconds)
> >                  TEXT/HTML-MIME-TYPE '() (list (string->bytes/utf-8 s))))
> > (define (file-not-found r)
> >   (response/xexpr "File not found."))
> >
> > (module+ main
> >   (file-stream-buffer-mode (current-output-port) 'line)
> >   (define (main)
> >     (displayln "Now serving...")
> >     (serve/servlet dispatch
> >                    ;; #:servlet-namespace '("shared-model.rkt")
> >                    #:stateless? #t
> >                    #:log-file (build-path "logs/httpd.log")
> >                    #:port 1111
> >                    #:listen-ip "127.0.0.1"
> >                    #:servlet-path "/"
> >                    #:servlet-regexp #rx""
> >                    #:extra-files-paths (list (build-path "pub/"))
> >                    #:server-root-path (build-path "/")
> >                    #:file-not-found-responder file-not-found))
> >   (main))
> >
> > --- shared-model.rkt
> >
> > ---------------------
> >
> > #lang racket/base
> > (define in-memory-database (make-parameter #f))
> > (define (in-memory-db-set-and-get x)
> >   (in-memory-database (format "~a: data to be shared across servlets" x))
> >   (in-memory-database))
> >
> > (define (get-in-memory-results [refresh? #f])
> >   (if refresh?
> >       (begin (displayln "database: force refresh")
> >              (in-memory-db-set-and-get "forced"))
> >       (let ([in-memory-db (in-memory-database)])
> >         (if in-memory-db
> >             (begin (displayln "database: cache hit")
> >                    in-memory-db)
> >             (begin (displayln "database: cache miss")
> >                    (in-memory-db-set-and-get "miss"))))))
> > (provide (all-defined-out))

-- 
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/oK0c1egYscwcfX3s2BvEdmTaixowdUBh9MXQnS4DZccwd9QqOnfUtyvWfx0LEbgmNoj3JqwVc7QKN2ugP2RgjbSU0OUafdoSpGB5ltdXn7s%3D%40protonmail.com.

Reply via email to