MFlow  Create and maintain dynamic Web applications as easy and fast as console applications
Thou shall not write request handlers
 This release: 11/06/2014. (@agocorona) <>< . issues & bugs .  Mflow Source code,     source code of this site

Caching AJAX responses to navigate a dataset in the browser using composable caching directives

What is the killer appication of the JavasCript frameworks?  To present data sets without repeated acesses to the server using the new HTML5 cache.

Now the new composable cache policies of MFlow permits the use of aggresive caching policies even for highly dynamic pages, since expressing cache directives is in the hands of the programmer of each particular widget, instead of HTTP gurus. The "separation of concern" preclude the synergies between components.

This example show how the small javascript programs generated by witerate and dField are cached to navigate the infinite dataset of the natural numbers in both directions without roundtrips to the server.

To understand how it works see:

Composable caching: Now the programmer can express independently the caching policies for each widget

Running example

(in the light red box):
Read from the server at: 2019-03-22 02:29:20.000108 UTC
next prev

Source code:

{-# LANGUAGE CPP, DeriveDataTypeable #-}
module CachingDataset where
import Data.Typeable
import Control.Monad
import Data.Time

-- #define ALONE -- to execute it alone, uncomment this
#ifdef ALONE
import MFlow.Wai.Blaze.Html.All
main= runNavigation "" $ transientNav cachingDataset
import MFlow.Wai.Blaze.Html.All hiding(page)
import Menu
newtype NextReg = NextReg Int deriving Typeable

cachingDataset= do
   page $ iterateResults [1..] 5  **> wlink () << b << "exit"
   iterateResults allnames n= pageFlow "d" $ witerate $  do
      maxAge 200
      time <- liftIO getCurrentTime
      b << "Read from the server at: " ++> dField(wraw . fromStr $ show time) <++ br
      NextReg ind <- getSessionData `onNothing` return (NextReg 0)
      foldl (**>) noWidget [dField(getData i ) <++ br | i <- [ind .. ind + n - 1]]
      r <-     dField (wlink (next ind ) << b << "next" ) <++ fromStr " "
           <|> dField (wlink (prev ind ) << b << "prev")
           <|> restp
      setSessionData $ NextReg r

      getData i =  wraw . fromStr . show $ allnames !! i

      next i  =  i + n
      prev i  = case i >= n of True ->  i - n; _ -> i

comments powered by Disqus