fix(memcached): navAccess & quick actions cache invalidations
This commit is contained in:
parent
9afee89a09
commit
d05306a39a
@ -313,7 +313,7 @@ falseAP = APPure . const . const . const $ falseAR <$> ask -- included for compl
|
|||||||
data AuthContext = AuthContext
|
data AuthContext = AuthContext
|
||||||
{ authCtxAuth :: Maybe UserId
|
{ authCtxAuth :: Maybe UserId
|
||||||
, authCtxBearer :: Maybe (BearerToken UniWorX)
|
, authCtxBearer :: Maybe (BearerToken UniWorX)
|
||||||
, authActiveTags :: Set AuthTag
|
, authActiveTags :: AuthTagActive
|
||||||
} deriving (Eq, Read, Show, Generic, Typeable)
|
} deriving (Eq, Read, Show, Generic, Typeable)
|
||||||
deriving anyclass (Hashable, Binary)
|
deriving anyclass (Hashable, Binary)
|
||||||
|
|
||||||
@ -323,10 +323,15 @@ getAuthContext :: forall m.
|
|||||||
, MonadCatch m
|
, MonadCatch m
|
||||||
)
|
)
|
||||||
=> m AuthContext
|
=> m AuthContext
|
||||||
getAuthContext = AuthContext
|
getAuthContext = do
|
||||||
<$> maybeAuthId
|
authCtx <- AuthContext
|
||||||
<*> runMaybeT (exceptTMaybe askBearerUnsafe)
|
<$> maybeAuthId
|
||||||
<*> (fromMaybe def <$> lookupSessionJson SessionActiveAuthTags)
|
<*> runMaybeT (exceptTMaybe askBearerUnsafe)
|
||||||
|
<*> (fromMaybe def <$> lookupSessionJson SessionActiveAuthTags)
|
||||||
|
|
||||||
|
$logDebugS "getAuthContext" $ tshow authCtx
|
||||||
|
|
||||||
|
return authCtx
|
||||||
|
|
||||||
|
|
||||||
askBearerUnsafe :: forall m.
|
askBearerUnsafe :: forall m.
|
||||||
@ -1713,7 +1718,7 @@ instance Yesod UniWorX where
|
|||||||
-- return ((,) <$> langBoxRes <*> urlRes, toWidget csrf <> fvInput urlView <> fvInput langBoxView)
|
-- return ((,) <$> langBoxRes <*> urlRes, toWidget csrf <> fvInput urlView <> fvInput langBoxView)
|
||||||
|
|
||||||
data MemcachedKeyFavourites
|
data MemcachedKeyFavourites
|
||||||
= MemcachedKeyFavouriteQuickActions CourseId AuthContext
|
= MemcachedKeyFavouriteQuickActions CourseId AuthContext (NonEmpty Lang)
|
||||||
deriving (Eq, Read, Show, Generic, Typeable)
|
deriving (Eq, Read, Show, Generic, Typeable)
|
||||||
deriving anyclass (Hashable, Binary)
|
deriving anyclass (Hashable, Binary)
|
||||||
|
|
||||||
@ -1856,7 +1861,8 @@ siteLayout' headingOverride widget = do
|
|||||||
in runMaybeT . guardOnM (unTermKey courseTerm `elem` favouriteTerms) . lift $ do
|
in runMaybeT . guardOnM (unTermKey courseTerm `elem` favouriteTerms) . lift $ do
|
||||||
ctx <- getAuthContext
|
ctx <- getAuthContext
|
||||||
MsgRenderer mr <- getMsgRenderer
|
MsgRenderer mr <- getMsgRenderer
|
||||||
let cK = MemcachedKeyFavouriteQuickActions cId ctx
|
langs <- selectLanguages appLanguages <$> languages
|
||||||
|
let cK = MemcachedKeyFavouriteQuickActions cId ctx langs
|
||||||
$logDebugS "FavouriteQuickActions" $ tshow cK <> " Checking..."
|
$logDebugS "FavouriteQuickActions" $ tshow cK <> " Checking..."
|
||||||
items <- memcachedLimitedKeyTimeoutBy
|
items <- memcachedLimitedKeyTimeoutBy
|
||||||
MemcachedLimitKeyFavourites appFavouritesQuickActionsBurstsize appFavouritesQuickActionsAvgInverseRate 1
|
MemcachedLimitKeyFavourites appFavouritesQuickActionsBurstsize appFavouritesQuickActionsAvgInverseRate 1
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
module Handler.Utils.Memcached
|
module Handler.Utils.Memcached
|
||||||
( memcached, memcachedBy
|
( memcachedAvailable
|
||||||
|
, memcached, memcachedBy
|
||||||
, memcachedHere, memcachedByHere
|
, memcachedHere, memcachedByHere
|
||||||
, memcachedSet, memcachedGet
|
, memcachedSet, memcachedGet
|
||||||
, memcachedInvalidate, memcachedByInvalidate
|
, memcachedInvalidate, memcachedByInvalidate
|
||||||
@ -76,6 +77,12 @@ _MemcachedExpiry = prism' fromExpiry toExpiry
|
|||||||
= Left . posixSecondsToUTCTime $ fromIntegral n
|
= Left . posixSecondsToUTCTime $ fromIntegral n
|
||||||
|
|
||||||
|
|
||||||
|
memcachedAvailable :: ( MonadHandler m, HandlerSite m ~ UniWorX
|
||||||
|
)
|
||||||
|
=> m Bool
|
||||||
|
memcachedAvailable = getsYesod $ is _Just . appMemcached
|
||||||
|
|
||||||
|
|
||||||
data MemcachedException = MemcachedException Memcached.MemcachedException
|
data MemcachedException = MemcachedException Memcached.MemcachedException
|
||||||
| MemcachedInvalidExpiry Expiry
|
| MemcachedInvalidExpiry Expiry
|
||||||
deriving (Show, Typeable)
|
deriving (Show, Typeable)
|
||||||
@ -102,7 +109,7 @@ memcachedByGet k = runMaybeT $ do
|
|||||||
|
|
||||||
encVal <- fmap toStrict . hoist liftIO . catchMaybeT (Proxy @Memcached.MemcachedException) $ Memcached.get_ cKey conn
|
encVal <- fmap toStrict . hoist liftIO . catchMaybeT (Proxy @Memcached.MemcachedException) $ Memcached.get_ cKey conn
|
||||||
|
|
||||||
$logInfoS "memcached" "Cache hit"
|
$logDebugS "memcached" "Cache hit"
|
||||||
|
|
||||||
guard $ length encVal >= Saltine.secretBoxNonce + Saltine.secretBoxMac
|
guard $ length encVal >= Saltine.secretBoxNonce + Saltine.secretBoxMac
|
||||||
let (nonceBS, encrypted) = splitAt Saltine.secretBoxNonce encVal
|
let (nonceBS, encrypted) = splitAt Saltine.secretBoxNonce encVal
|
||||||
@ -133,7 +140,7 @@ memcachedBySet mExp k v = do
|
|||||||
let cKey = memcachedKey aeadKey (Proxy @a) k
|
let cKey = memcachedKey aeadKey (Proxy @a) k
|
||||||
encVal = Saltine.encode nonce <> AEAD.aead aeadKey nonce (toStrict $ Binary.encode v) cKey
|
encVal = Saltine.encode nonce <> AEAD.aead aeadKey nonce (toStrict $ Binary.encode v) cKey
|
||||||
liftIO $ Memcached.set zeroBits (fromMaybe zeroBits mExp') cKey (fromStrict encVal) conn
|
liftIO $ Memcached.set zeroBits (fromMaybe zeroBits mExp') cKey (fromStrict encVal) conn
|
||||||
$logInfoS "memcached" "Cache store"
|
$logDebugS "memcached" "Cache store"
|
||||||
|
|
||||||
memcachedByInvalidate :: forall a k m p.
|
memcachedByInvalidate :: forall a k m p.
|
||||||
( MonadHandler m, HandlerSite m ~ UniWorX
|
( MonadHandler m, HandlerSite m ~ UniWorX
|
||||||
@ -365,8 +372,8 @@ memcachedAsync = unsafePerformIO . newTVarIO $ HashMap.empty
|
|||||||
{-# NOINLINE memcachedAsync #-}
|
{-# NOINLINE memcachedAsync #-}
|
||||||
|
|
||||||
liftAsyncTimeout :: forall k'' a m.
|
liftAsyncTimeout :: forall k'' a m.
|
||||||
( MonadResource m, MonadUnliftIO m
|
( MonadHandler m, HandlerSite m ~ UniWorX
|
||||||
, MonadLogger m
|
, MonadUnliftIO m
|
||||||
, MonadThrow m
|
, MonadThrow m
|
||||||
, Typeable k'', Hashable k'', Eq k''
|
, Typeable k'', Hashable k'', Eq k''
|
||||||
, Typeable a
|
, Typeable a
|
||||||
@ -374,7 +381,7 @@ liftAsyncTimeout :: forall k'' a m.
|
|||||||
=> DiffTime
|
=> DiffTime
|
||||||
-> k''
|
-> k''
|
||||||
-> m a -> MaybeT m a
|
-> m a -> MaybeT m a
|
||||||
liftAsyncTimeout dt (hashableDynamic -> cK) act = do
|
liftAsyncTimeout dt (hashableDynamic -> cK) act = ifNotM memcachedAvailable (lift act) $ do
|
||||||
delay <- liftIO . newDelay . round $ toRational dt * 1e6
|
delay <- liftIO . newDelay . round $ toRational dt * 1e6
|
||||||
|
|
||||||
act' <- lift $ do
|
act' <- lift $ do
|
||||||
@ -418,8 +425,8 @@ liftAsyncTimeout dt (hashableDynamic -> cK) act = do
|
|||||||
| otherwise
|
| otherwise
|
||||||
= throwM AsyncTimeoutReturnTypeDoesNotMatchComputationKey
|
= throwM AsyncTimeoutReturnTypeDoesNotMatchComputationKey
|
||||||
|
|
||||||
memcachedTimeoutWith :: ( MonadResource m, MonadUnliftIO m
|
memcachedTimeoutWith :: ( MonadHandler m, HandlerSite m ~ UniWorX
|
||||||
, MonadLogger m
|
, MonadUnliftIO m
|
||||||
, MonadThrow m
|
, MonadThrow m
|
||||||
, Typeable k'', Hashable k'', Eq k''
|
, Typeable k'', Hashable k'', Eq k''
|
||||||
, Typeable a
|
, Typeable a
|
||||||
|
|||||||
@ -25,6 +25,8 @@ import Database.Persist.Sql
|
|||||||
|
|
||||||
import Utils.Lens.TH
|
import Utils.Lens.TH
|
||||||
|
|
||||||
|
import qualified Data.Binary as Binary
|
||||||
|
|
||||||
|
|
||||||
data AuthenticationMode = AuthLDAP
|
data AuthenticationMode = AuthLDAP
|
||||||
| AuthPWHash { authPWHash :: Text }
|
| AuthPWHash { authPWHash :: Text }
|
||||||
@ -109,6 +111,13 @@ instance FromJSON AuthTagActive where
|
|||||||
o' <- parseJSON $ Aeson.Object o :: Aeson.Parser (HashMap AuthTag Bool)
|
o' <- parseJSON $ Aeson.Object o :: Aeson.Parser (HashMap AuthTag Bool)
|
||||||
return . AuthTagActive $ \n -> fromMaybe (authTagIsActive def n) $ HashMap.lookup n o'
|
return . AuthTagActive $ \n -> fromMaybe (authTagIsActive def n) $ HashMap.lookup n o'
|
||||||
|
|
||||||
|
instance Hashable AuthTagActive where
|
||||||
|
hashWithSalt s = foldl' hashWithSalt s . authTagIsActive
|
||||||
|
|
||||||
|
instance Binary AuthTagActive where
|
||||||
|
put v = Binary.put . HashMap.fromList $ map (id &&& authTagIsActive v) universeF
|
||||||
|
get = Binary.get <&> \hm -> AuthTagActive (\n -> fromMaybe (authTagIsActive def n) $ HashMap.lookup n hm)
|
||||||
|
|
||||||
derivePersistFieldJSON ''AuthTagActive
|
derivePersistFieldJSON ''AuthTagActive
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user