Skip to content

Commit 215dba1

Browse files
authored
Merge pull request #815 from IntersectMBO/jordan/LocalStateQueryExpr-refactor
Make continuation construction clearer in query monadic interface
2 parents d7571df + 2fe9ab8 commit 215dba1

File tree

1 file changed

+44
-10
lines changed
  • cardano-api/src/Cardano/Api/Internal/IPC

1 file changed

+44
-10
lines changed

cardano-api/src/Cardano/Api/Internal/IPC/Monad.hs

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,20 @@ setupLocalStateQueryExpr
8383
setupLocalStateQueryExpr waitDone mPointVar' resultVar' ntcVersion f =
8484
LocalStateQueryClient . pure . Net.Query.SendMsgAcquire mPointVar' $
8585
Net.Query.ClientStAcquiring
86-
{ Net.Query.recvMsgAcquired = runContT (runReaderT (runLocalStateQueryExpr f) ntcVersion) $ \result -> do
87-
atomically $ putTMVar resultVar' (Right result)
88-
void $ atomically waitDone -- Wait for all protocols to complete before exiting.
89-
pure $ Net.Query.SendMsgRelease $ pure $ Net.Query.SendMsgDone ()
86+
{ Net.Query.recvMsgAcquired =
87+
let allQueries = runReaderT (runLocalStateQueryExpr f) ntcVersion
88+
in runContT allQueries finalContinuation
9089
, Net.Query.recvMsgFailure = \failure -> do
9190
atomically $ putTMVar resultVar' (Left (toAcquiringFailure failure))
9291
void $ atomically waitDone -- Wait for all protocols to complete before exiting.
9392
pure $ Net.Query.SendMsgDone ()
9493
}
94+
where
95+
-- We wait for all queries to finish before exiting.
96+
finalContinuation result = do
97+
atomically $ putTMVar resultVar' (Right result)
98+
void $ atomically waitDone -- Wait for all protocols to complete before exiting.
99+
pure $ Net.Query.SendMsgRelease $ pure $ Net.Query.SendMsgDone ()
95100

96101
-- | Get the node server's Node-to-Client version.
97102
getNtcVersion :: LocalStateQueryExpr block point QueryInMode r IO NodeToClientVersion
@@ -105,10 +110,39 @@ queryExpr q = do
105110
ntcVersion <- getNtcVersion
106111
case isQuerySupportedInNtcVersion (toConsensusQuery q) ntcVersion of
107112
Right () ->
108-
fmap Right . LocalStateQueryExpr . ReaderT $ \_ -> ContT $ \f ->
109-
pure $
110-
Net.Query.SendMsgQuery q $
111-
Net.Query.ClientStQuerying
112-
{ Net.Query.recvMsgResult = f
113-
}
113+
fmap Right . LocalStateQueryExpr . ReaderT $ \_ -> constructQueryContinuation q
114114
Left err -> pure $ Left err
115+
116+
{- The client sends a query with the following data constructor:
117+
118+
data ClientStAcquired block point query m a where
119+
SendMsgQuery :: query result
120+
-> ClientStQuerying block point query m a result
121+
-> ClientStAcquired block point query m a
122+
123+
The client is then awaiting a result from the server which is represented by:
124+
125+
data ClientStQuerying block point query m a result = ClientStQuerying {
126+
recvMsgResult :: result -> m (ClientStAcquired block point query m a)
127+
}
128+
129+
When constructing the `ClientStQuerying` value we can send another query (`SendMsgQuery`) or
130+
release (`SendMsgRelease`) and this recursion is nicely modelled with the `ContT` monad transformer.
131+
132+
The final continuation in our case is waiting for all the queries to be returned and then returning
133+
`SendMsgRelease`.
134+
-}
135+
constructQueryContinuation
136+
:: Applicative m
137+
=> QueryInMode result
138+
-> ContT
139+
(Net.Query.ClientStAcquired block point QueryInMode m a)
140+
m
141+
result
142+
constructQueryContinuation q = do
143+
ContT $ \final ->
144+
pure $
145+
Net.Query.SendMsgQuery q $
146+
Net.Query.ClientStQuerying
147+
{ Net.Query.recvMsgResult = final
148+
}

0 commit comments

Comments
 (0)