hedis-pile-0.4.0: Caching mandatory data with Redis

Safe HaskellSafe-Infered



Solution for caching mandatory data with Redis.

In many cases, requires not just pick up or put the data into the cache. As a rule, data are required.

... check the cache ... if the value is missing, run the calculations ... put value to cache ... Tedious

Solution is quite simple - collapse all of these steps in one operation.





:: forall ma . (MonadIO ma, ma ~ Redis) 
=> ByteString

Prefix for key and tags.

-> ByteString

Key in cache. Key will be stored as prefix:key

-> Maybe (ByteString, ByteString)

Optional expect field.

-> Maybe ByteString

Optional payload field. This reduces time complexity of request data from the cache from O(N) to O(1). Regardless of setting this field, all data from computation will stored in cache.

-> (forall mb. MonadIO mb => mb ([(ByteString, ByteString)], Maybe Integer, [ByteString]))

Computation that returns data and optional TTL and tags. All tags will be stored as prefix:tag.

-> ma (Maybe [(ByteString, ByteString)]) 

Stores computation results in Redis as hashSet. Computation fires only if data absent in cache. Of course, to refresh the data, they must first remove from the cache.

Computation controls all that will be stored in the cache except two things: key and prefix for keys and tags. To do this, with the results of computation, it may return optional TTL in seconds (Redis convention) and tags for key. About tags see Database.Redis.Tags.

Instead get all data from cache, optional parameter allows simply make sure that cache holds HashSet with needed field with needed value. If this is so, pile return Nothing.

 conn <- connect defaultConnectInfo
 runRedis conn $ do
    -- do it
    r <- pile "myprefix" "mykey" (Just ("etag", "etag")) Nothing $  
        return ([("etag", "etag"), ("val", "myval")], Nothing, [])
    liftIO $ print r
    -- Just [("etag", "etag"), ("val", "myval")]
    -- once again
    r <- pile "myprefix" "mykey" (Just ("etag", "etag")) Nothing $  
        return ([("etag", "etag"), ("val", "myval")], Nothing, [])
    liftIO $ print r
    -- Nothing
    -- and again without expect
    r <- pile "myprefix" "mykey" Nothing Nothing $  
        return ([("etag", "etag"), ("val", "myval")], Nothing, [])
    liftIO $ print r
    -- Just [("etag", "etag"), ("val", "myval")]

Time complexity for cached data:

  • O(1) If expect matches.
  • O(2) If payload field provided