2015-11-11 16 views
7

Tôi đang cố gắng sử dụng cached chức năng để ngăn chặn các truy vấn nhiều db trong widget và xử lý khác nhau:Làm thế nào để sử dụng bộ đệm ẩn cho mỗi yêu cầu?

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 

Và trong một widget ở đâu đó:

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

này biên dịch nhưng truy vấn để có được ID vẫn chạy nhiều lần.

Tôi đang làm gì sai? Hoặc là có một cách tốt hơn để chỉ nhận được bob một lần và sử dụng anh ta trong mọi xử lý và phụ tùng?

+0

Không thực sự đọc mã bên trong câu hỏi (vì tôi đã gặp sự cố với 'cache '). Ai đó sẽ nhận được 200 điểm thật sự dễ dàng. – Cthulhu

Trả lời

3

Tôi khá mới để Yesod, nhưng tôi nghĩ rằng bạn chỉ cần tinh chỉnh getBob

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

Vấn đề là getBob chức năng hiện tại của bạn bắt đầu do khối với a <- getBob'. Hãy nhớ rằng do khối chuỗi hành động đơn thuần, vì vậy bạn thực sự kết thúc cuộc gọi getBob' điều đầu tiên mỗi khi getBob được gọi. Trong một cách mỉa mai, sau khi bạn đã thực hiện điều này, bạn tạo một phiên bản được lưu trong bộ xử lý trả về những gì bạn vừa nhận được từ getBob', nhưng cuối cùng sẽ truy vấn phiên bản được lưu trong bộ nhớ cache chính xác một lần (ngay sau đó với c <- cached b). phạm vi và bộ thu gom rác nhận được nó.

Trong giải pháp tôi trình bày ở trên, bạn quấn bất cứ điều gì getBob' cung cấp cho bạn trong CachedBobId. Sau đó, bạn vượt qua trình xử lý đó CachedBobId <$> getBob' :: Handler (CachedBobId BobId), đến cached, cung cấp cho bạn một trình xử lý khác cached (CachedBobId <$> getBob') cùng loại, nhưng với bộ nhớ đệm. Cuối cùng, bạn trích xuất bất kỳ trình xử lý được lưu trong bộ nhớ cache nào cung cấp cho bạn để lấy lại một Handler BobId.

Các vấn đề liên quan