2015-11-11 17 views
7

sto cercando di utilizzare la funzione cached per evitare che più query db in diversi widgets e gestori:Come utilizzare la cache di yesod per richiesta?

newtype CachedBobId key 
    = CachedBobId { unCachedBobId :: key } 
    deriving Typeable 

getBob' :: Handler BobId 
getBob' = do 
    uncle <- runInputGet $ ireq textField "bobsuncle" 
    (Entity bob _) <- runDB $ getBy404 $ UniqueBob uncle 
    return bob 

getBob :: Handler BobId 
getBob = do 
    a <- getBob' 
    let b = return $ CachedBobId a 
    c <- cached b 
    return $ unCachedBobId c 

E in un widget da qualche parte:

renderDerp :: Widget 
renderDerp = do 
    --these are used in the shakespeare files 
    lolBob <- handlerToWidget $ getBob 
    nutherBob <- handlerToWidget $ getBob 
    $(widgetFile "test") 

Questo compila ma la query per ottenere la L'ID viene eseguito ancora più volte.

Cosa sto sbagliando? O c'è un modo migliore per ottenere bob solo una volta e usarlo in ogni gestore e widget?

+0

Non ha veramente letto il codice all'interno della domanda (poiché ho avuto un problema con 'cache anche '). Qualcuno otterrà davvero 200 punti facili. – Cthulhu

risposta

3

Sono abbastanza nuovo a Yesod, ma credo che solo bisogno di modificare getBob

getBob :: Handler BobId 
getBob = unCachedBobId <$> cached (CachedBobId <$> getBob') 

Il problema è che il vostro attuale funzione getBob inizia la sua do blocco con a <- getBob'. Ricorda che una sequenza di blocchi do azioni monodiche, quindi in realtà si finisce per chiamare getBob' prima cosa ogni volta che viene chiamato getBob. In modo ironico, dopo averlo fatto, crei una versione memorizzata nella cache di un gestore che restituisce ciò che hai appena ricevuto da getBob', ma finisci per interrogare quella versione memorizzata nella cache esattamente una volta (subito dopo con c <- cached b), poi cade fuori di scopo e il garbage collector lo ottiene.

Nella soluzione di cui sopra, si avvolge qualsiasi cosa getBob' ti dà in CachedBobId. Quindi, si passa il gestore CachedBobId <$> getBob' :: Handler (CachedBobId BobId) a cached, che restituisce un altro gestore cached (CachedBobId <$> getBob') dello stesso tipo, ma con la memorizzazione nella cache. Infine, si estrae qualsiasi cosa il gestore memorizzato nella cache ti restituisca un Handler BobId.

Problemi correlati