Browse Source

txmlconnector: request timeout

master
Denis Tereshkin 3 years ago
parent
commit
bc197a16e4
  1. 52
      src/TXMLConnector.hs

52
src/TXMLConnector.hs

@ -35,7 +35,7 @@ import Control.Concurrent.STM (TVar, atomically, modifyTVar',
tryReadTMVar, writeTVar) tryReadTMVar, writeTVar)
import Control.Concurrent.STM.TBQueue (TBQueue, newTBQueue, import Control.Concurrent.STM.TBQueue (TBQueue, newTBQueue,
readTBQueue, writeTBQueue) readTBQueue, writeTBQueue)
import Control.Monad (forever, void) import Control.Monad (forever, void, when)
import Data.Maybe (mapMaybe) import Data.Maybe (mapMaybe)
import qualified Data.Text as T import qualified Data.Text as T
import Text.XML.Light.Input (parseXML) import Text.XML.Light.Input (parseXML)
@ -85,7 +85,8 @@ import Control.Monad.IO.Class (MonadIO (liftIO))
import Control.Monad.Reader (ReaderT (runReaderT)) import Control.Monad.Reader (ReaderT (runReaderT))
import Control.Monad.Reader.Class (MonadReader, asks) import Control.Monad.Reader.Class (MonadReader, asks)
import qualified Data.Map.Strict as M import qualified Data.Map.Strict as M
import Data.Time.Clock (UTCTime, getCurrentTime) import Data.Time.Clock (UTCTime, diffUTCTime,
getCurrentTime)
import Prelude hiding (log) import Prelude hiding (log)
import TickerInfoServer (TickerInfo (..), import TickerInfoServer (TickerInfo (..),
TickerInfoServerHandle, TickerInfoServerHandle,
@ -118,7 +119,9 @@ newtype Request =
Request HistoryRequest Request HistoryRequest
deriving (Show, Eq, Ord) deriving (Show, Eq, Ord)
data Response = ResponseHistory HistoryResponse data Response =
ResponseHistory HistoryResponse
| ResponseTimeout
data HistoryResponse = data HistoryResponse =
HistoryResponse HistoryResponse
@ -135,6 +138,7 @@ data TXMLConnectorHandle =
, notificationQueue :: TBQueue TransaqResponse , notificationQueue :: TBQueue TransaqResponse
, hRequestVar :: TMVar Request , hRequestVar :: TMVar Request
, hResponseVar :: TMVar (TMVar Response) , hResponseVar :: TMVar (TMVar Response)
, hRequestTimestamp :: TVar UTCTime
} }
data ConnectionStage = StageConnection | StageGetInfo | StageConnected data ConnectionStage = StageConnection | StageGetInfo | StageConnected
@ -151,17 +155,18 @@ data TickKey = TickKey TickerId DataType
data Env = data Env =
Env Env
{ {
qssChannel :: BoundedChan QuoteSourceServerData qssChannel :: BoundedChan QuoteSourceServerData
, tisHandle :: TickerInfoServerHandle , tisHandle :: TickerInfoServerHandle
, requestVar :: TMVar Request , requestVar :: TMVar Request
, responseVar :: TMVar (TMVar Response) , responseVar :: TMVar (TMVar Response)
, currentCandles :: TVar [Candle] , requestTimestamp :: TVar UTCTime
, tickMap :: TVar (M.Map TickKey Tick) , currentCandles :: TVar [Candle]
, transaqQueue :: TBQueue TransaqResponse , tickMap :: TVar (M.Map TickKey Tick)
, logger :: LogAction IO Message , transaqQueue :: TBQueue TransaqResponse
, config :: TransaqConnectorConfig , logger :: LogAction IO Message
, serverConnected :: TVar ConnectionStage , config :: TransaqConnectorConfig
, candleKindMap :: TVar (M.Map Int Int) , serverConnected :: TVar ConnectionStage
, candleKindMap :: TVar (M.Map Int Int)
} }
newtype App a = App { unApp :: ReaderT Env IO a } newtype App a = App { unApp :: ReaderT Env IO a }
@ -186,6 +191,7 @@ start logger config qssChannel tisH = do
currentCandles <- newTVarIO [] currentCandles <- newTVarIO []
serverConnected <- liftIO $ newTVarIO StageConnection serverConnected <- liftIO $ newTVarIO StageConnection
candleKindMap <- newTVarIO M.empty candleKindMap <- newTVarIO M.empty
requestTimestamp <- getCurrentTime >>= newTVarIO
let env = let env =
Env Env
{ {
@ -193,6 +199,7 @@ start logger config qssChannel tisH = do
, tisHandle = tisH , tisHandle = tisH
, requestVar = requestVar , requestVar = requestVar
, responseVar = responseVar , responseVar = responseVar
, requestTimestamp = requestTimestamp
, currentCandles = currentCandles , currentCandles = currentCandles
, tickMap = tickTable , tickMap = tickTable
, transaqQueue = notificationQueue , transaqQueue = notificationQueue
@ -310,6 +317,21 @@ workThread = do
} }
_ -> log Warning "TXMLConnector.WorkThread" $ "Unable to parse security ID: " <> hrTickerId request _ -> log Warning "TXMLConnector.WorkThread" $ "Unable to parse security ID: " <> hrTickerId request
_ -> log Warning "TXMLConnector.WorkThread" $ "Invalid candlekind requested" <> (T.pack . show . unBarTimeframe . hrTimeframe $ request) _ -> log Warning "TXMLConnector.WorkThread" $ "Invalid candlekind requested" <> (T.pack . show . unBarTimeframe . hrTimeframe $ request)
checkRequestTimeout
requestTimeout = 10
checkRequestTimeout = do
now <- liftIO getCurrentTime
tsVar <- asks requestTimestamp
ts <- liftIO $ readTVarIO tsVar
when (now `diffUTCTime` ts >= requestTimeout) $ do
resp <- asks responseVar >>= liftIO . atomically . tryReadTMVar
case resp of
Just tmvar -> do
log Warning "TXMLConnector.WorkThread" "Request timeout"
liftIO . atomically . putTMVar tmvar $ ResponseTimeout
_ -> pure ()
handleGetInfo :: App () handleGetInfo :: App ()
handleGetInfo = do handleGetInfo = do
@ -474,8 +496,10 @@ makeTickerId sec = board sec <> "#" <> seccode sec
makeRequest :: TXMLConnectorHandle -> Request -> IO Response makeRequest :: TXMLConnectorHandle -> Request -> IO Response
makeRequest h request = do makeRequest h request = do
now <- getCurrentTime
resp <- atomically $ do resp <- atomically $ do
resp <- newEmptyTMVar resp <- newEmptyTMVar
writeTVar (hRequestTimestamp h) now
putTMVar (hResponseVar h) resp putTMVar (hResponseVar h) resp
putTMVar (hRequestVar h) request putTMVar (hRequestVar h) request
pure resp pure resp

Loading…
Cancel
Save