Use stm channels
This commit is contained in:
parent
b66318d5ea
commit
9e0781dff5
3 changed files with 11 additions and 8 deletions
|
@ -19,7 +19,7 @@ env:
|
||||||
- GHCVER=8.2.2 CABALVER=1.24 MONGO=3.4 STACKAGE=lts-11.6
|
- GHCVER=8.2.2 CABALVER=1.24 MONGO=3.4 STACKAGE=lts-11.6
|
||||||
- GHCVER=8.0.2 CABALVER=1.24 MONGO=3.6 STACKAGE=lts-9.21
|
- GHCVER=8.0.2 CABALVER=1.24 MONGO=3.6 STACKAGE=lts-9.21
|
||||||
- GHCVER=8.2.2 CABALVER=1.24 MONGO=3.6 STACKAGE=lts-11.6
|
- GHCVER=8.2.2 CABALVER=1.24 MONGO=3.6 STACKAGE=lts-11.6
|
||||||
- GHCVER=8.4.2 CABALVER=2.2.0.1 MONGO=3.6 STACKAGE=nightly
|
- GHCVER=8.4.2 CABALVER=2.2 MONGO=3.6 STACKAGE=nightly
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,9 @@ import System.IO.Unsafe (unsafePerformIO)
|
||||||
import Data.Maybe (maybeToList)
|
import Data.Maybe (maybeToList)
|
||||||
import GHC.Conc (ThreadStatus(..), threadStatus)
|
import GHC.Conc (ThreadStatus(..), threadStatus)
|
||||||
import Control.Monad (forever)
|
import Control.Monad (forever)
|
||||||
import Control.Concurrent.Chan (Chan, newChan, readChan, writeChan, isEmptyChan)
|
import Control.Monad.STM (atomically)
|
||||||
import Control.Concurrent (ThreadId, killThread, forkFinally)
|
import Control.Concurrent (ThreadId, killThread, forkFinally)
|
||||||
|
import Control.Concurrent.STM.TChan (TChan, newTChan, readTChan, writeTChan, isEmptyTChan)
|
||||||
|
|
||||||
import Control.Exception.Lifted (onException, throwIO, try)
|
import Control.Exception.Lifted (onException, throwIO, try)
|
||||||
|
|
||||||
|
@ -87,7 +88,7 @@ mkWeakMVar = addMVarFinalizer
|
||||||
-- | Thread-safe and pipelined connection
|
-- | Thread-safe and pipelined connection
|
||||||
data Pipeline = Pipeline
|
data Pipeline = Pipeline
|
||||||
{ vStream :: MVar Transport -- ^ Mutex on handle, so only one thread at a time can write to it
|
{ vStream :: MVar Transport -- ^ Mutex on handle, so only one thread at a time can write to it
|
||||||
, responseQueue :: Chan (MVar (Either IOError Response)) -- ^ Queue of threads waiting for responses. Every time a response arrive we pop the next thread and give it the response.
|
, responseQueue :: TChan (MVar (Either IOError Response)) -- ^ Queue of threads waiting for responses. Every time a response arrive we pop the next thread and give it the response.
|
||||||
, listenThread :: ThreadId
|
, listenThread :: ThreadId
|
||||||
, finished :: MVar ()
|
, finished :: MVar ()
|
||||||
, serverData :: ServerData
|
, serverData :: ServerData
|
||||||
|
@ -106,14 +107,14 @@ data ServerData = ServerData
|
||||||
newPipeline :: ServerData -> Transport -> IO Pipeline
|
newPipeline :: ServerData -> Transport -> IO Pipeline
|
||||||
newPipeline serverData stream = do
|
newPipeline serverData stream = do
|
||||||
vStream <- newMVar stream
|
vStream <- newMVar stream
|
||||||
responseQueue <- newChan
|
responseQueue <- atomically newTChan
|
||||||
finished <- newEmptyMVar
|
finished <- newEmptyMVar
|
||||||
let drainReplies = do
|
let drainReplies = do
|
||||||
chanEmpty <- isEmptyChan responseQueue
|
chanEmpty <- atomically $ isEmptyTChan responseQueue
|
||||||
if chanEmpty
|
if chanEmpty
|
||||||
then return ()
|
then return ()
|
||||||
else do
|
else do
|
||||||
var <- readChan responseQueue
|
var <- atomically $ readTChan responseQueue
|
||||||
putMVar var $ Left $ mkIOError
|
putMVar var $ Left $ mkIOError
|
||||||
doesNotExistErrorType
|
doesNotExistErrorType
|
||||||
"Handle has been closed"
|
"Handle has been closed"
|
||||||
|
@ -159,7 +160,7 @@ listen Pipeline{..} = do
|
||||||
stream <- readMVar vStream
|
stream <- readMVar vStream
|
||||||
forever $ do
|
forever $ do
|
||||||
e <- try $ readMessage stream
|
e <- try $ readMessage stream
|
||||||
var <- readChan responseQueue
|
var <- atomically $ readTChan responseQueue
|
||||||
putMVar var e
|
putMVar var e
|
||||||
case e of
|
case e of
|
||||||
Left err -> Tr.close stream >> ioError err -- close and stop looping
|
Left err -> Tr.close stream >> ioError err -- close and stop looping
|
||||||
|
@ -182,7 +183,7 @@ pcall p@Pipeline{..} message = do
|
||||||
doCall stream = do
|
doCall stream = do
|
||||||
writeMessage stream message
|
writeMessage stream message
|
||||||
var <- newEmptyMVar
|
var <- newEmptyMVar
|
||||||
liftIO $ writeChan responseQueue var
|
liftIO $ atomically $ writeTChan responseQueue var
|
||||||
return $ readMVar var >>= either throwIO return -- return promise
|
return $ readMVar var >>= either throwIO return -- return promise
|
||||||
|
|
||||||
-- * Pipe
|
-- * Pipe
|
||||||
|
|
|
@ -42,6 +42,7 @@ Library
|
||||||
, monad-control >= 0.3.1
|
, monad-control >= 0.3.1
|
||||||
, lifted-base >= 0.1.0.3
|
, lifted-base >= 0.1.0.3
|
||||||
, pureMD5
|
, pureMD5
|
||||||
|
, stm
|
||||||
, tagged
|
, tagged
|
||||||
, tls >= 1.3.0
|
, tls >= 1.3.0
|
||||||
, time
|
, time
|
||||||
|
@ -106,6 +107,7 @@ Benchmark bench
|
||||||
, cryptohash -any
|
, cryptohash -any
|
||||||
, network -any
|
, network -any
|
||||||
, nonce >= 1.0.5
|
, nonce >= 1.0.5
|
||||||
|
, stm
|
||||||
, parsec -any
|
, parsec -any
|
||||||
, random -any
|
, random -any
|
||||||
, random-shuffle -any
|
, random-shuffle -any
|
||||||
|
|
Loading…
Reference in a new issue