Browse Source

TXMLConnector: correct shutdown

master
Denis Tereshkin 3 years ago
parent
commit
569811ae2a
  1. 31
      src/TXMLConnector.hs

31
src/TXMLConnector.hs

@ -9,6 +9,7 @@
module TXMLConnector module TXMLConnector
( (
start start
, TXMLConnector.stop
, Request(..) , Request(..)
, HistoryRequest(..) , HistoryRequest(..)
, Response(..) , Response(..)
@ -37,6 +38,7 @@ import Control.Concurrent.STM (TVar, atomically, modifyTVar',
import Control.Concurrent.STM.TBQueue (TBQueue, newTBQueue, import Control.Concurrent.STM.TBQueue (TBQueue, newTBQueue,
readTBQueue, writeTBQueue) readTBQueue, writeTBQueue)
import Control.Monad (forever, void, when) import Control.Monad (forever, void, when)
import Control.Monad.Extra (whileM)
import qualified Data.Bimap as BM import qualified Data.Bimap as BM
import Data.Maybe (mapMaybe) import Data.Maybe (mapMaybe)
import qualified Data.Text as T import qualified Data.Text as T
@ -165,14 +167,16 @@ data TXMLConnectorHandle =
, hResponseVar :: TMVar (TMVar Response) , hResponseVar :: TMVar (TMVar Response)
, hRequestTimestamp :: TVar UTCTime , hRequestTimestamp :: TVar UTCTime
, hNotificationCallback :: TVar (Maybe (BrokerBackendNotification -> IO ())) , hNotificationCallback :: TVar (Maybe (BrokerBackendNotification -> IO ()))
, hRunVar :: TMVar ()
} }
data ConnectionStage = StageConnection | StageGetInfo | StageConnected data ConnectionStage = StageConnection | StageGetInfo | StageConnected | StageShutdown
deriving (Eq, Show, Ord) deriving (Eq, Show, Ord)
data MainQueueData = data MainQueueData =
MainQueueTransaqData TransaqResponse MainQueueTransaqData TransaqResponse
| MainQueueRequest Request | MainQueueRequest Request
| MainQueueShutdown
deriving (Eq, Show) deriving (Eq, Show)
data TickKey = TickKey TickerId DataType data TickKey = TickKey TickerId DataType
@ -208,6 +212,7 @@ data Env =
, serverConnected :: TVar ConnectionStage , serverConnected :: TVar ConnectionStage
, candleKindMap :: TVar (M.Map Int Int) , candleKindMap :: TVar (M.Map Int Int)
, brokerState :: BrokerState , brokerState :: BrokerState
, runVar :: TMVar ()
} }
newtype App a = App { unApp :: ReaderT Env IO a } newtype App a = App { unApp :: ReaderT Env IO a }
@ -237,6 +242,7 @@ start logger config qssChannel tisH = do
notificationCallback <- newTVarIO Nothing notificationCallback <- newTVarIO Nothing
orderTransactionIdMap <- newTVarIO BM.empty orderTransactionIdMap <- newTVarIO BM.empty
pendingOrders <- newTVarIO (fromList []) pendingOrders <- newTVarIO (fromList [])
runVar <- newEmptyTMVarIO
let brokerState = let brokerState =
BrokerState BrokerState
{ {
@ -261,6 +267,7 @@ start logger config qssChannel tisH = do
, serverConnected = serverConnected , serverConnected = serverConnected
, candleKindMap = candleKindMap , candleKindMap = candleKindMap
, brokerState = brokerState , brokerState = brokerState
, runVar = runVar
} }
threadId <- forkIO $ (runReaderT . unApp) workThread env threadId <- forkIO $ (runReaderT . unApp) workThread env
return $ TXMLConnectorHandle return $ TXMLConnectorHandle
@ -271,8 +278,12 @@ start logger config qssChannel tisH = do
, hResponseVar = responseVar , hResponseVar = responseVar
, hRequestTimestamp = requestTimestamp , hRequestTimestamp = requestTimestamp
, hNotificationCallback = notificationCallback , hNotificationCallback = notificationCallback
, hRunVar = runVar
} }
stop :: TXMLConnectorHandle -> IO ()
stop h = atomically $ putTMVar (hRunVar h) ()
workThread :: App () workThread :: App ()
workThread = do workThread = do
cfg <- asks config cfg <- asks config
@ -286,12 +297,16 @@ workThread = do
case rc of case rc of
Nothing -> log Error "TXMLConnector.WorkThread" "Unable to set callback" Nothing -> log Error "TXMLConnector.WorkThread" "Unable to set callback"
Just cb -> do Just cb -> do
void $ forever $ do serverConnectionState <- asks serverConnected
connStatus <- asks serverConnected >>= (liftIO . readTVarIO) void $ whileM $ do
connStatus <- liftIO . readTVarIO $ serverConnectionState
case connStatus of case connStatus of
StageConnection -> handleUnconnected StageConnection -> handleUnconnected
StageGetInfo -> handleGetInfo StageGetInfo -> handleGetInfo
StageConnected -> handleConnected StageConnected -> handleConnected
StageShutdown -> pure ()
pure $ connStatus /= StageShutdown
liftIO $ freeCallback cb liftIO $ freeCallback cb
where where
parseTransaqLogLevel 1 = TXML.Warning parseTransaqLogLevel 1 = TXML.Warning
@ -299,7 +314,6 @@ workThread = do
parseTransaqLogLevel _ = TXML.Info parseTransaqLogLevel _ = TXML.Info
parseAndWrite queue logger xml = do parseAndWrite queue logger xml = do
let parsed = mapMaybe parseContent $ parseXML xml let parsed = mapMaybe parseContent $ parseXML xml
logWith logger Debug "TXML.Callback" $ "Parsed entities: " <> (T.pack . show . length) parsed
mapM_ (writeToQueue queue) parsed mapM_ (writeToQueue queue) parsed
pure True pure True
parseContent (Elem el) = parseElement el parseContent (Elem el) = parseElement el
@ -321,11 +335,15 @@ workThread = do
writeToQueue queue resp = atomically $ writeTBQueue queue resp writeToQueue queue resp = atomically $ writeTBQueue queue resp
handleConnected :: App () handleConnected :: App ()
handleConnected = do handleConnected = do
serverConn <- asks serverConnected
rqVar <- asks requestVar rqVar <- asks requestVar
runVar' <- asks runVar
queue <- asks transaqQueue queue <- asks transaqQueue
item <- liftIO . atomically $ (MainQueueTransaqData <$> readTBQueue queue) `orElse` item <- liftIO . atomically $ (MainQueueTransaqData <$> readTBQueue queue) `orElse`
(MainQueueRequest <$> takeTMVar rqVar) (MainQueueRequest <$> takeTMVar rqVar) `orElse`
(takeTMVar runVar' >> pure MainQueueShutdown)
case item of case item of
MainQueueShutdown -> liftIO $ atomically $ writeTVar serverConn StageShutdown
MainQueueTransaqData transaqData -> do MainQueueTransaqData transaqData -> do
tm <- asks tickMap tm <- asks tickMap
case transaqData of case transaqData of
@ -569,6 +587,7 @@ workThread = do
log Warning "TXMLConnector.WorkThread" $ "Unable to connect: [" <> err <> "]" log Warning "TXMLConnector.WorkThread" $ "Unable to connect: [" <> err <> "]"
liftIO $ threadDelay (1000 * 1000 * 10) liftIO $ threadDelay (1000 * 1000 * 10)
Right _ -> do Right _ -> do
log Warning "TXMLConnector.WorkThread" "Connected"
conn <- asks serverConnected conn <- asks serverConnected
liftIO . atomically $ writeTVar conn StageGetInfo liftIO . atomically $ writeTVar conn StageGetInfo
-- item <- atomically $ readTBQueue queue -- item <- atomically $ readTBQueue queue
@ -737,5 +756,5 @@ brSetNotificationCallback h cb = atomically $ writeTVar (hNotificationCallback h
makeBrokerBackend :: TXMLConnectorHandle -> T.Text -> BrokerBackend makeBrokerBackend :: TXMLConnectorHandle -> T.Text -> BrokerBackend
makeBrokerBackend h account = makeBrokerBackend h account =
BrokerBackend [account] (brSetNotificationCallback h) (brSubmitOrder h) (brCancelOrder h) (pure ()) BrokerBackend [account] (brSetNotificationCallback h) (brSubmitOrder h) (brCancelOrder h) (TXMLConnector.stop h)

Loading…
Cancel
Save