Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
299 additions
and
220 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
{-# LANGUAGE OverloadedStrings #-} | ||
module Language.Marlowe.Runtime.ContractCaching (refreshContracts) where | ||
|
||
import Language.Marlowe.Runtime.Types.ContractsJSON ( Range(..), ContractList(..), ContractListISeq, ResultList(ResultList, results), ContractInList ) | ||
import qualified Language.Marlowe.Runtime.Types.LazyFeed as LazyFeed | ||
import qualified Language.Marlowe.Runtime.Types.IndexedSeq as ISeq | ||
import Language.Marlowe.Runtime.Types.LazyFeed (LazyFeed) | ||
import Data.ByteString (ByteString) | ||
import Network.HTTP.Simple (HttpException, Request, parseRequest, setRequestHeader, setRequestMethod, httpLBS, getResponseBody, getResponseHeader) | ||
import Data.Time.Clock (getCurrentTime) | ||
import Data.Foldable (foldl') | ||
import Control.Exception (try, Exception (displayException)) | ||
import Data.Aeson (eitherDecode) | ||
|
||
refreshContracts :: String -> ContractListISeq -> IO (Either String ContractList) | ||
refreshContracts endpoint lOldChain = do | ||
eresult <- updateContracts endpoint lOldChain | ||
now <- getCurrentTime | ||
return $ do contracts <- eresult | ||
return (ContractList { clRetrievedTime = Just now | ||
, clContracts = contracts }) | ||
|
||
updateContracts :: String -> ContractListISeq -> IO (Either String ContractListISeq) | ||
updateContracts endpoint oldContracts = | ||
LazyFeed.foldThroughLazyFeed (completeOldContractList oldContracts) (getAllContracts endpoint) | ||
|
||
completeOldContractList :: ContractListISeq -> Maybe ContractInList | ||
-> Either ContractListISeq (ContractListISeq -> ContractListISeq) | ||
completeOldContractList oldList (Just h) = | ||
case ISeq.findMatchingTail h oldList of | ||
Just matchingTail -> Left matchingTail | ||
Nothing -> Right $ ISeq.cons h | ||
completeOldContractList _ Nothing = Left ISeq.empty | ||
|
||
getAllContracts :: String -> LazyFeed ContractInList | ||
getAllContracts endpoint = getAllContracts' endpoint Start | ||
|
||
setRangeHeader :: Range -> Request -> Request | ||
setRangeHeader (Next bs) = setRequestHeader "Range" [bs] | ||
setRangeHeader _ = id | ||
|
||
parseRangeHeader :: [ByteString] -> Range | ||
parseRangeHeader [bs] = Next bs | ||
parseRangeHeader _ = Done | ||
|
||
getAllContracts' :: String -> Range -> LazyFeed ContractInList | ||
getAllContracts' _endpoint Done = LazyFeed.emptyLazyFeed | ||
getAllContracts' endpoint range = LazyFeed.fromIO $ do | ||
initialRequest <- parseRequest $ endpoint <> "contracts" | ||
let request = foldl' (flip id) initialRequest | ||
[ setRequestMethod "GET" | ||
, setRequestHeader "Accept" ["application/json"] | ||
, setRangeHeader range | ||
] | ||
mResponse <- try (httpLBS request) | ||
case mResponse of | ||
Right response -> do | ||
case eitherDecode (getResponseBody response) of | ||
Right (ResultList { results = contracts }) -> do | ||
let nextRange = parseRangeHeader . getResponseHeader "Next-Range" $ response | ||
return $ LazyFeed.prependListToLazyFeed contracts (getAllContracts' endpoint nextRange) | ||
Left str2 -> return $ LazyFeed.errorToLazyFeed $ "Error decoding: " ++ str2 | ||
Left str -> return $ LazyFeed.errorToLazyFeed $ displayException (str :: HttpException) | ||
|
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.