Skip to content

Commit 2989890

Browse files
committed
add mapAllSessions
1 parent 69051cf commit 2989890

File tree

5 files changed

+31
-2
lines changed

5 files changed

+31
-2
lines changed

Spock.cabal

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: Spock
2-
version: 0.8.0.0
2+
version: 0.8.1.0
33
synopsis: Another Haskell web framework for rapid development
44
description: This toolbox provides everything you need to get a quick start into web hacking with haskell:
55
.
@@ -57,6 +57,7 @@ library
5757
case-insensitive >=1.1,
5858
containers >=0.5,
5959
directory >=1.2,
60+
focus >=0.1,
6061
hashable >=1.2,
6162
http-types >=0.8,
6263
hvect >= 0.2,

src/Web/Spock/Internal/SessionManager.hs

+10
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ createSessionManager cfg =
5555
, sm_writeSession = writeSessionImpl vaultKey cacheHM
5656
, sm_modifySession = modifySessionImpl vaultKey cacheHM
5757
, sm_clearAllSessions = clearAllSessionsImpl cacheHM
58+
, sm_mapSessions = mapAllSessionsImpl cacheHM
5859
, sm_middleware = sessionMiddleware cfg vaultKey cacheHM
5960
, sm_addSafeAction = addSafeActionImpl vaultKey cacheHM
6061
, sm_lookupSafeAction = lookupSafeActionImpl vaultKey cacheHM
@@ -289,6 +290,15 @@ clearAllSessionsImpl :: SV.SessionVault (Session conn sess st)
289290
clearAllSessionsImpl sessionRef =
290291
liftIO $ atomically $ SV.filterSessions (const False) sessionRef
291292

293+
mapAllSessionsImpl ::
294+
SV.SessionVault (Session conn sess st)
295+
-> (sess -> STM sess)
296+
-> SpockAction conn sess st ()
297+
mapAllSessionsImpl sessionRef f =
298+
liftIO $ atomically $ flip SV.mapSessions sessionRef $ \sess ->
299+
do newData <- f (sess_data sess)
300+
return $ sess { sess_data = newData }
301+
292302
housekeepSessions :: SessionCfg sess
293303
-> SV.SessionVault (Session conn sess st)
294304
-> (HM.HashMap SessionId (Session conn sess st) -> IO ())

src/Web/Spock/Internal/SessionVault.hs

+8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import Control.Applicative
1212
import Control.Concurrent.STM (STM)
1313
import Control.Monad
1414
import Data.Hashable
15+
import Focus as F
1516
import qualified ListT as L
1617
import qualified STMContainers.Map as STMMap
1718
import qualified Data.Text as T
@@ -55,3 +56,10 @@ filterSessions cond sv =
5556
map getSessionKey $
5657
filter (not . cond) allVals
5758
forM_ deleteKeys $ flip deleteSession sv
59+
60+
-- | Perform action on all sessions
61+
mapSessions :: IsSession s => (s -> STM s) -> SessionVault s -> STM ()
62+
mapSessions f sv@(SessionVault smap) =
63+
do allVals <- toList sv
64+
forM_ allVals $ \sess ->
65+
STMMap.focus (F.adjustM f) (getSessionKey sess) smap

src/Web/Spock/Internal/Types.hs

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Web.Spock.Internal.Wire
1616
#else
1717
import Control.Applicative
1818
#endif
19+
import Control.Concurrent.STM
1920
import Control.Monad.Base
2021
import Control.Monad.Reader
2122
import Control.Monad.Trans.Control
@@ -200,6 +201,7 @@ data SessionManager conn sess st
200201
, sm_readSession :: SpockAction conn sess st sess
201202
, sm_writeSession :: sess -> SpockAction conn sess st ()
202203
, sm_modifySession :: forall a. (sess -> (sess, a)) -> SpockAction conn sess st a
204+
, sm_mapSessions :: (sess -> STM sess) -> SpockAction conn sess st ()
203205
, sm_clearAllSessions :: SpockAction conn sess st ()
204206
, sm_middleware :: Middleware
205207
, sm_addSafeAction :: PackedSafeAction conn sess st -> SpockAction conn sess st SafeActionHash

src/Web/Spock/Shared.hs

+9-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ module Web.Spock.Shared
3434
, SessionPersistCfg(..), readShowSessionPersist
3535
, SessionId
3636
, getSessionId, readSession, writeSession
37-
, modifySession, modifySession', modifyReadSession, clearAllSessions
37+
, modifySession, modifySession', modifyReadSession, mapAllSessions, clearAllSessions
3838
-- * Internals for extending Spock
3939
, getSpockHeart, runSpockIO, WebStateM, WebState
4040
)
@@ -45,6 +45,7 @@ import Web.Spock.Internal.SessionManager
4545
import Web.Spock.Internal.Types
4646
import Web.Spock.Internal.CoreAction
4747
import Control.Monad
48+
import Control.Concurrent.STM (STM)
4849
import System.Directory
4950
import qualified Web.Spock.Internal.Wire as W
5051
import qualified Network.Wai as Wai
@@ -106,6 +107,13 @@ clearAllSessions =
106107
do mgr <- getSessMgr
107108
sm_clearAllSessions mgr
108109

110+
-- | Apply a transformation to all sessions. Be careful with this, as this
111+
-- may cause many STM transaction retries.
112+
mapAllSessions :: (sess -> STM sess) -> SpockAction conn sess st ()
113+
mapAllSessions f =
114+
do mgr <- getSessMgr
115+
sm_mapSessions mgr f
116+
109117
-- | Simple session persisting configuration. DO NOT USE IN PRODUCTION
110118
readShowSessionPersist :: (Read a, Show a) => FilePath -> SessionPersistCfg a
111119
readShowSessionPersist fp =

0 commit comments

Comments
 (0)