diff options
author | Joe Crayne <joe@jerkface.net> | 2020-01-03 17:12:14 -0500 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2020-01-03 17:26:06 -0500 |
commit | 5181c77ce7dd73d622ff3921b90bf2741bedb646 (patch) | |
tree | 16ba93b83ad0c137a013e47f593d7d40ace68ce6 | |
parent | 31b799222cb76cd0002d9a3cc5b340a7b6fed139 (diff) |
QueryResponse: Use three-way sum to distinguish Canceled and Timedout.
-rw-r--r-- | dht/src/Network/BitTorrent/MainlineDHT.hs | 21 | ||||
-rw-r--r-- | dht/src/Network/Tox/DHT/Handlers.hs | 8 | ||||
-rw-r--r-- | dht/src/Network/Tox/Onion/Handlers.hs | 2 | ||||
-rw-r--r-- | dht/src/Network/Tox/Onion/Routes.hs | 2 | ||||
-rw-r--r-- | dht/src/Network/Tox/TCP.hs | 10 | ||||
-rw-r--r-- | server/src/Network/QueryResponse.hs | 35 |
6 files changed, 46 insertions, 32 deletions
diff --git a/dht/src/Network/BitTorrent/MainlineDHT.hs b/dht/src/Network/BitTorrent/MainlineDHT.hs index bb556bc6..e604f5e5 100644 --- a/dht/src/Network/BitTorrent/MainlineDHT.hs +++ b/dht/src/Network/BitTorrent/MainlineDHT.hs | |||
@@ -1033,21 +1033,22 @@ announceH (SwarmsDatabase peers toks _) naddr announcement = do | |||
1033 | isReadonlyClient :: MainlineClient -> Bool | 1033 | isReadonlyClient :: MainlineClient -> Bool |
1034 | isReadonlyClient client = False -- TODO | 1034 | isReadonlyClient client = False -- TODO |
1035 | 1035 | ||
1036 | mainlineSend :: ( BEncode a | 1036 | mainlineSend :: ( BEncode xqry |
1037 | , BEncode a2 | 1037 | , BEncode xrsp |
1038 | ) => Method | 1038 | ) => Method |
1039 | -> (a2 -> b) | 1039 | -> (xrsp -> rsp) |
1040 | -> (t -> a) | 1040 | -> (qry -> xqry) |
1041 | -> MainlineClient | 1041 | -> MainlineClient |
1042 | -> t | 1042 | -> qry |
1043 | -> NodeInfo | 1043 | -> NodeInfo |
1044 | -> IO (Maybe b) | 1044 | -> IO (Maybe rsp) |
1045 | mainlineSend meth unwrap msg client nid addr = do | 1045 | mainlineSend meth unwrap msg client nid addr = do |
1046 | reply <- sendQuery client serializer (msg nid) addr | 1046 | reply <- sendQuery client serializer (msg nid) addr |
1047 | -- sendQuery will return (Just (Left _)) on a parse error. We're going to | 1047 | return $ case reply of |
1048 | -- blow it away with the join-either sequence. | 1048 | Success (Right x) -> Just x |
1049 | -- TODO: Do something with parse errors. | 1049 | Success (Left e) -> Nothing -- TODO: Do something with parse errors. |
1050 | return $ join $ either (const Nothing) Just <$> reply | 1050 | Canceled -> Nothing |
1051 | TimedOut -> Nothing | ||
1051 | where | 1052 | where |
1052 | serializer = MethodSerializer | 1053 | serializer = MethodSerializer |
1053 | { methodTimeout = \ni -> return (ni, 5000000) | 1054 | { methodTimeout = \ni -> return (ni, 5000000) |
diff --git a/dht/src/Network/Tox/DHT/Handlers.hs b/dht/src/Network/Tox/DHT/Handlers.hs index 7806da78..dc4ca5fa 100644 --- a/dht/src/Network/Tox/DHT/Handlers.hs +++ b/dht/src/Network/Tox/DHT/Handlers.hs | |||
@@ -353,7 +353,7 @@ ping client addr = do | |||
353 | dput XPing $ show addr ++ " <-- ping" | 353 | dput XPing $ show addr ++ " <-- ping" |
354 | reply <- QR.sendQuery client (serializer PingType DHTPing unpong) Ping addr | 354 | reply <- QR.sendQuery client (serializer PingType DHTPing unpong) Ping addr |
355 | dput XPing $ show addr ++ " -pong-> " ++ show reply | 355 | dput XPing $ show addr ++ " -pong-> " ++ show reply |
356 | maybe (return False) (\Pong -> return True) $ join reply | 356 | maybe (return False) (\Pong -> return True) $ join $ resultToMaybe reply |
357 | 357 | ||
358 | 358 | ||
359 | saveCookieKey :: TVar [(SockAddr, (Int, PublicKey))] -> SockAddr -> PublicKey -> STM () | 359 | saveCookieKey :: TVar [(SockAddr, (Int, PublicKey))] -> SockAddr -> PublicKey -> STM () |
@@ -396,7 +396,7 @@ cookieRequest crypto client localUserKey addr = do | |||
396 | reply <- QR.sendQuery client cookieSerializer cookieRequest addr | 396 | reply <- QR.sendQuery client cookieSerializer cookieRequest addr |
397 | runlast | 397 | runlast |
398 | dput XNetCrypto $ show addr ++ " -cookieResponse-> " ++ show reply | 398 | dput XNetCrypto $ show addr ++ " -cookieResponse-> " ++ show reply |
399 | return $ join reply | 399 | return $ join $ resultToMaybe reply |
400 | 400 | ||
401 | unCookie :: DHTMessage t -> Maybe (t (Cookie Encrypted)) | 401 | unCookie :: DHTMessage t -> Maybe (t (Cookie Encrypted)) |
402 | unCookie (DHTCookie n24 fcookie) = Just fcookie | 402 | unCookie (DHTCookie n24 fcookie) = Just fcookie |
@@ -415,7 +415,7 @@ getNodes client cbvar nid addr = do | |||
415 | -- dput XMisc $ show addr ++ " <-- getnodes " ++ show nid | 415 | -- dput XMisc $ show addr ++ " <-- getnodes " ++ show nid |
416 | reply <- QR.sendQuery client (serializer GetNodesType DHTGetNodes unsendNodes) (GetNodes nid) addr | 416 | reply <- QR.sendQuery client (serializer GetNodesType DHTGetNodes unsendNodes) (GetNodes nid) addr |
417 | -- dput XMisc $ show addr ++ " -sendnodes-> " ++ show reply | 417 | -- dput XMisc $ show addr ++ " -sendnodes-> " ++ show reply |
418 | forM_ (join reply) $ \(SendNodes ns) -> | 418 | forM_ (join $ resultToMaybe reply) $ \(SendNodes ns) -> |
419 | forM_ ns $ \n -> do | 419 | forM_ ns $ \n -> do |
420 | now <- getPOSIXTime | 420 | now <- getPOSIXTime |
421 | atomically $ do | 421 | atomically $ do |
@@ -423,7 +423,7 @@ getNodes client cbvar nid addr = do | |||
423 | forM_ mcbs $ \cbs -> do | 423 | forM_ mcbs $ \cbs -> do |
424 | forM_ cbs $ \cb -> do | 424 | forM_ cbs $ \cb -> do |
425 | rumoredAddress cb now addr (udpNodeInfo n) | 425 | rumoredAddress cb now addr (udpNodeInfo n) |
426 | return $ fmap unwrapNodes $ join reply | 426 | return $ fmap unwrapNodes $ join $ resultToMaybe reply |
427 | 427 | ||
428 | getNodesUDP :: Client -> TVar (HashMap NodeId [NodeInfoCallback]) -> NodeId -> NodeInfo -> IO (Maybe ([NodeInfo],[NodeInfo],Maybe ())) | 428 | getNodesUDP :: Client -> TVar (HashMap NodeId [NodeInfoCallback]) -> NodeId -> NodeInfo -> IO (Maybe ([NodeInfo],[NodeInfo],Maybe ())) |
429 | getNodesUDP client cbvar nid addr = getNodes client cbvar nid (Multi.UDP ==> addr) | 429 | getNodesUDP client cbvar nid addr = getNodes client cbvar nid (Multi.UDP ==> addr) |
diff --git a/dht/src/Network/Tox/Onion/Handlers.hs b/dht/src/Network/Tox/Onion/Handlers.hs index 65ec846c..fa7bc83c 100644 --- a/dht/src/Network/Tox/Onion/Handlers.hs +++ b/dht/src/Network/Tox/Onion/Handlers.hs | |||
@@ -285,7 +285,7 @@ sendOnion getTimeout client req oaddr unwrap = | |||
285 | forM_ mb $ \r -> dput XAnnounce $ show (onionNodeInfo oaddr) ++ " sent response: " ++ show r | 285 | forM_ mb $ \r -> dput XAnnounce $ show (onionNodeInfo oaddr) ++ " sent response: " ++ show r |
286 | maybe (if n>0 then loop $! n - 1 else return Nothing) | 286 | maybe (if n>0 then loop $! n - 1 else return Nothing) |
287 | (return . Just . unwrap (onionNodeInfo oaddr)) | 287 | (return . Just . unwrap (onionNodeInfo oaddr)) |
288 | $ join mb | 288 | $ join $ resultToMaybe mb |
289 | 289 | ||
290 | 290 | ||
291 | -- | Lookup the secret counterpart for a given alias key. | 291 | -- | Lookup the secret counterpart for a given alias key. |
diff --git a/dht/src/Network/Tox/Onion/Routes.hs b/dht/src/Network/Tox/Onion/Routes.hs index b20ad7dd..7c11227a 100644 --- a/dht/src/Network/Tox/Onion/Routes.hs +++ b/dht/src/Network/Tox/Onion/Routes.hs | |||
@@ -171,7 +171,7 @@ newOnionRouter crypto perror tcp_enabled = do | |||
171 | ((tbl,(tcptbl,tcpcons,relaynet,onionnet)),tcp) <- do | 171 | ((tbl,(tcptbl,tcpcons,relaynet,onionnet)),tcp) <- do |
172 | (tcptbl, client) <- TCP.newClient crypto | 172 | (tcptbl, client) <- TCP.newClient crypto |
173 | id | 173 | id |
174 | (. (Just . (,) False)) | 174 | (. (Success . (,) False)) |
175 | (lookupSender' pq rlog) | 175 | (lookupSender' pq rlog) |
176 | (\_ (RouteId rid) -> atomically $ fmap storedRoute <$> readArray rm rid) | 176 | (\_ (RouteId rid) -> atomically $ fmap storedRoute <$> readArray rm rid) |
177 | 177 | ||
diff --git a/dht/src/Network/Tox/TCP.hs b/dht/src/Network/Tox/TCP.hs index 9f0af976..0850ce51 100644 --- a/dht/src/Network/Tox/TCP.hs +++ b/dht/src/Network/Tox/TCP.hs | |||
@@ -46,7 +46,7 @@ import DPut | |||
46 | import Network.Address (setPort,PortNumber,localhost4,fromSockAddr,nullAddress4) | 46 | import Network.Address (setPort,PortNumber,localhost4,fromSockAddr,nullAddress4) |
47 | import Network.Kademlia.Routing | 47 | import Network.Kademlia.Routing |
48 | import Network.Kademlia.Search hiding (sendQuery) | 48 | import Network.Kademlia.Search hiding (sendQuery) |
49 | import Network.QueryResponse | 49 | import Network.QueryResponse as QR |
50 | import Network.QueryResponse.TCP | 50 | import Network.QueryResponse.TCP |
51 | import Network.Tox.TCP.NodeId () | 51 | import Network.Tox.TCP.NodeId () |
52 | import Network.Tox.DHT.Transport (toxSpace) | 52 | import Network.Tox.DHT.Transport (toxSpace) |
@@ -226,7 +226,7 @@ getUDPNodes tcp seeking dst = fmap fst <$> getUDPNodes' tcp seeking dst | |||
226 | getUDPNodes' :: TCPClient err Nonce8 -> NodeId -> UDP.NodeInfo -> IO (Maybe (([UDP.NodeInfo], [UDP.NodeInfo], Maybe ()), NodeInfo)) | 226 | getUDPNodes' :: TCPClient err Nonce8 -> NodeId -> UDP.NodeInfo -> IO (Maybe (([UDP.NodeInfo], [UDP.NodeInfo], Maybe ()), NodeInfo)) |
227 | getUDPNodes' tcp seeking dst0 = do | 227 | getUDPNodes' tcp seeking dst0 = do |
228 | mgateway <- atomically $ tcpGetGateway tcp dst0 | 228 | mgateway <- atomically $ tcpGetGateway tcp dst0 |
229 | fmap join $ forM mgateway $ \gateway -> do | 229 | fmap (join . fmap resultToMaybe) $ forM mgateway $ \gateway -> do |
230 | (b,c,n24) <- atomically $ do | 230 | (b,c,n24) <- atomically $ do |
231 | b <- transportNewKey (tcpCrypto tcp) | 231 | b <- transportNewKey (tcpCrypto tcp) |
232 | c <- transportNewKey (tcpCrypto tcp) | 232 | c <- transportNewKey (tcpCrypto tcp) |
@@ -284,7 +284,7 @@ handle2route o src dst = do | |||
284 | tcpPing :: Show addr => Client err PacketNumber Nonce8 addr (Bool,RelayPacket) -> addr -> IO (Maybe ()) | 284 | tcpPing :: Show addr => Client err PacketNumber Nonce8 addr (Bool,RelayPacket) -> addr -> IO (Maybe ()) |
285 | tcpPing client dst = do | 285 | tcpPing client dst = do |
286 | dput XTCP $ "tcpPing " ++ show dst | 286 | dput XTCP $ "tcpPing " ++ show dst |
287 | sendQuery client meth () dst | 287 | resultToMaybe <$> sendQuery client meth () dst |
288 | where meth = MethodSerializer | 288 | where meth = MethodSerializer |
289 | { wrapQuery = \n8 src dst () -> (True,RelayPing n8) | 289 | { wrapQuery = \n8 src dst () -> (True,RelayPing n8) |
290 | , unwrapResponse = \_ -> () | 290 | , unwrapResponse = \_ -> () |
@@ -295,7 +295,7 @@ tcpPing client dst = do | |||
295 | tcpConnectionRequest_ :: Client err PacketNumber tid addr (Bool, RelayPacket) | 295 | tcpConnectionRequest_ :: Client err PacketNumber tid addr (Bool, RelayPacket) |
296 | -> PublicKey -> addr -> IO (Maybe ConId) | 296 | -> PublicKey -> addr -> IO (Maybe ConId) |
297 | tcpConnectionRequest_ client pubkey ni = do | 297 | tcpConnectionRequest_ client pubkey ni = do |
298 | sendQuery client meth pubkey ni | 298 | resultToMaybe <$> sendQuery client meth pubkey ni |
299 | where | 299 | where |
300 | meth = MethodSerializer | 300 | meth = MethodSerializer |
301 | { wrapQuery = \n8 src dst pubkey -> (True,RoutingRequest pubkey) | 301 | { wrapQuery = \n8 src dst pubkey -> (True,RoutingRequest pubkey) |
@@ -319,7 +319,7 @@ type RelayCache = TCPCache (SessionProtocol (SessionData,RelayPacket) RelayPacke | |||
319 | -- defaults are 'id' and 'tryPutMVar'. The resulting customized table state | 319 | -- defaults are 'id' and 'tryPutMVar'. The resulting customized table state |
320 | -- will be returned to the caller along with the new client. | 320 | -- will be returned to the caller along with the new client. |
321 | newClient :: TransportCrypto | 321 | newClient :: TransportCrypto |
322 | -> ((Maybe (Bool,RelayPacket) -> IO ()) -> a) -- ^ store mvar for relay query | 322 | -> ((QR.Result (Bool,RelayPacket) -> IO ()) -> a) -- ^ store mvar for relay query |
323 | -> (a -> RelayPacket -> IO void) -- ^ load mvar for relay query | 323 | -> (a -> RelayPacket -> IO void) -- ^ load mvar for relay query |
324 | -> (SockAddr -> Nonce8 -> IO (Maybe (OnionDestination RouteId))) -- ^ lookup sender of onion query | 324 | -> (SockAddr -> Nonce8 -> IO (Maybe (OnionDestination RouteId))) -- ^ lookup sender of onion query |
325 | -> (UDP.NodeInfo -> RouteId -> IO (Maybe OnionRoute)) -- ^ lookup OnionRoute by id | 325 | -> (UDP.NodeInfo -> RouteId -> IO (Maybe OnionRoute)) -- ^ lookup OnionRoute by id |
diff --git a/server/src/Network/QueryResponse.hs b/server/src/Network/QueryResponse.hs index 20e7ecf0..cb65eb47 100644 --- a/server/src/Network/QueryResponse.hs +++ b/server/src/Network/QueryResponse.hs | |||
@@ -2,6 +2,9 @@ | |||
2 | -- with Kademlia implementations in mind. | 2 | -- with Kademlia implementations in mind. |
3 | 3 | ||
4 | {-# LANGUAGE CPP #-} | 4 | {-# LANGUAGE CPP #-} |
5 | {-# LANGUAGE DeriveFoldable #-} | ||
6 | {-# LANGUAGE DeriveFunctor #-} | ||
7 | {-# LANGUAGE DeriveTraversable #-} | ||
5 | {-# LANGUAGE GADTs #-} | 8 | {-# LANGUAGE GADTs #-} |
6 | {-# LANGUAGE LambdaCase #-} | 9 | {-# LANGUAGE LambdaCase #-} |
7 | {-# LANGUAGE PartialTypeSignatures #-} | 10 | {-# LANGUAGE PartialTypeSignatures #-} |
@@ -32,6 +35,7 @@ import qualified Data.IntMap.Strict as IntMap | |||
32 | import qualified Data.Map.Strict as Map | 35 | import qualified Data.Map.Strict as Map |
33 | ;import Data.Map.Strict (Map) | 36 | ;import Data.Map.Strict (Map) |
34 | import Data.Time.Clock.POSIX | 37 | import Data.Time.Clock.POSIX |
38 | import Data.Traversable (Traversable) | ||
35 | import qualified Data.Word64Map as W64Map | 39 | import qualified Data.Word64Map as W64Map |
36 | ;import Data.Word64Map (Word64Map) | 40 | ;import Data.Word64Map (Word64Map) |
37 | import Data.Word | 41 | import Data.Word |
@@ -49,6 +53,15 @@ import DPut | |||
49 | import DebugTag | 53 | import DebugTag |
50 | import Data.TableMethods | 54 | import Data.TableMethods |
51 | 55 | ||
56 | -- | The reply to a query to a remote server or the result of some other IO | ||
57 | -- process that can timeout or be canceled. | ||
58 | data Result a = Success a | TimedOut | Canceled | ||
59 | deriving (Functor, Foldable, Traversable, Eq, Ord, Show) | ||
60 | |||
61 | resultToMaybe :: Result a -> Maybe a | ||
62 | resultToMaybe (Success a) = Just a | ||
63 | resultToMaybe _ = Nothing | ||
64 | |||
52 | -- | An inbound packet or condition raised while monitoring a connection. | 65 | -- | An inbound packet or condition raised while monitoring a connection. |
53 | data Arrival err addr x | 66 | data Arrival err addr x |
54 | = Terminated -- ^ Virtual message that signals EOF. | 67 | = Terminated -- ^ Virtual message that signals EOF. |
@@ -310,7 +323,7 @@ data TransactionMethods d qid addr x = TransactionMethods | |||
310 | -- that can be used to forget the 'MVar' if the remote peer is not | 323 | -- that can be used to forget the 'MVar' if the remote peer is not |
311 | -- responding. | 324 | -- responding. |
312 | dispatchRegister :: POSIXTime -- time of expiry | 325 | dispatchRegister :: POSIXTime -- time of expiry |
313 | -> (Maybe x -> IO ()) -- callback upon response (or timeout) | 326 | -> (Result x -> IO ()) -- callback upon response (or timeout) |
314 | -> addr | 327 | -> addr |
315 | -> d | 328 | -> d |
316 | -> STM (qid, d) | 329 | -> STM (qid, d) |
@@ -394,7 +407,7 @@ asyncQuery_ :: Client err meth tid addr x | |||
394 | -> MethodSerializer tid addr x meth a b | 407 | -> MethodSerializer tid addr x meth a b |
395 | -> a | 408 | -> a |
396 | -> addr | 409 | -> addr |
397 | -> (Maybe b -> IO ()) | 410 | -> (Result b -> IO ()) |
398 | -> IO (tid,POSIXTime,Int) | 411 | -> IO (tid,POSIXTime,Int) |
399 | asyncQuery_ (Client net d err pending whoami _) meth q addr0 withResponse = do | 412 | asyncQuery_ (Client net d err pending whoami _) meth q addr0 withResponse = do |
400 | now <- getPOSIXTime | 413 | now <- getPOSIXTime |
@@ -419,14 +432,14 @@ asyncQuery :: Show meth => Client err meth tid addr x | |||
419 | -> MethodSerializer tid addr x meth a b | 432 | -> MethodSerializer tid addr x meth a b |
420 | -> a | 433 | -> a |
421 | -> addr | 434 | -> addr |
422 | -> (Maybe b -> IO ()) | 435 | -> (Result b -> IO ()) |
423 | -> IO () | 436 | -> IO () |
424 | asyncQuery client meth q addr withResponse0 = do | 437 | asyncQuery client meth q addr withResponse0 = do |
425 | tm <- getSystemTimerManager | 438 | tm <- getSystemTimerManager |
426 | tidvar <- newEmptyMVar | 439 | tidvar <- newEmptyMVar |
427 | timedout <- registerTimeout tm 1000000 $ do | 440 | timedout <- registerTimeout tm 1000000 $ do |
428 | dput XMisc $ "async TIMEDOUT " ++ show (method meth) | 441 | dput XMisc $ "async TIMEDOUT " ++ show (method meth) |
429 | withResponse0 Nothing | 442 | withResponse0 TimedOut |
430 | tid <- takeMVar tidvar | 443 | tid <- takeMVar tidvar |
431 | dput XMisc $ "async TIMEDOUT mvar " ++ show (method meth) | 444 | dput XMisc $ "async TIMEDOUT mvar " ++ show (method meth) |
432 | case client of | 445 | case client of |
@@ -448,16 +461,16 @@ sendQuery :: | |||
448 | -> MethodSerializer tid addr x meth a b -- ^ Information for marshaling the query. | 461 | -> MethodSerializer tid addr x meth a b -- ^ Information for marshaling the query. |
449 | -> a -- ^ The outbound query. | 462 | -> a -- ^ The outbound query. |
450 | -> addr -- ^ Destination address of query. | 463 | -> addr -- ^ Destination address of query. |
451 | -> IO (Maybe b) -- ^ The response, or 'Nothing' if it timed out. | 464 | -> IO (Result b) -- ^ The response or failure condition. |
452 | sendQuery c@(Client net d err pending whoami _) meth q addr0 = do | 465 | sendQuery c@(Client net d err pending whoami _) meth q addr0 = do |
453 | mvar <- newEmptyMVar | 466 | mvar <- newEmptyMVar |
454 | (tid,now,expiry) <- asyncQuery_ c meth q addr0 $ mapM_ (putMVar mvar) | 467 | (tid,now,expiry) <- asyncQuery_ c meth q addr0 $ mapM_ (putMVar mvar) |
455 | mres <- timeout expiry $ takeMVar mvar | 468 | mres <- timeout expiry $ takeMVar mvar |
456 | case mres of | 469 | case mres of |
457 | Just b -> return $ Just b | 470 | Just b -> return $ Success b |
458 | Nothing -> do | 471 | Nothing -> do |
459 | atomically $ readTVar pending >>= dispatchCancel (tableMethods d) tid >>= writeTVar pending | 472 | atomically $ readTVar pending >>= dispatchCancel (tableMethods d) tid >>= writeTVar pending |
460 | return Nothing | 473 | return TimedOut |
461 | 474 | ||
462 | contramapAddr :: (a -> b) -> MethodHandler err tid b x -> MethodHandler err tid a x | 475 | contramapAddr :: (a -> b) -> MethodHandler err tid b x -> MethodHandler err tid a x |
463 | contramapAddr f (MethodHandler p s a) | 476 | contramapAddr f (MethodHandler p s a) |
@@ -495,8 +508,8 @@ dispatchQuery (NoReply unwrapQ f) tid self x addr = | |||
495 | -- table of pending transactions. This also enables multiple 'Client's to | 508 | -- table of pending transactions. This also enables multiple 'Client's to |
496 | -- share a single transaction table. | 509 | -- share a single transaction table. |
497 | transactionMethods' :: | 510 | transactionMethods' :: |
498 | ((Maybe x -> IO ()) -> a) -- ^ store MVar into table entry | 511 | ((Result x -> IO ()) -> a) -- ^ store MVar into table entry |
499 | -> (a -> Maybe x -> IO void) -- ^ load MVar from table entry | 512 | -> (a -> Result x -> IO void) -- ^ load MVar from table entry |
500 | -> TableMethods t tid -- ^ Table methods to lookup values by /tid/. | 513 | -> TableMethods t tid -- ^ Table methods to lookup values by /tid/. |
501 | -> (g -> (tid,g)) -- ^ Generate a new unique /tid/ value and update the generator state /g/. | 514 | -> (g -> (tid,g)) -- ^ Generate a new unique /tid/ value and update the generator state /g/. |
502 | -> TransactionMethods (g,t a) tid addr x | 515 | -> TransactionMethods (g,t a) tid addr x |
@@ -509,7 +522,7 @@ transactionMethods' store load (TableMethods insert delete lookup) generate = Tr | |||
509 | , dispatchResponse = \tid x (g,t) -> | 522 | , dispatchResponse = \tid x (g,t) -> |
510 | case lookup tid t of | 523 | case lookup tid t of |
511 | Just v -> let t' = delete tid t | 524 | Just v -> let t' = delete tid t |
512 | in return ((g,t'),void $ load v $ Just x) | 525 | in return ((g,t'),void $ load v $ Success x) |
513 | Nothing -> return ((g,t), return ()) | 526 | Nothing -> return ((g,t), return ()) |
514 | } | 527 | } |
515 | 528 | ||
@@ -518,7 +531,7 @@ transactionMethods' store load (TableMethods insert delete lookup) generate = Tr | |||
518 | transactionMethods :: | 531 | transactionMethods :: |
519 | TableMethods t tid -- ^ Table methods to lookup values by /tid/. | 532 | TableMethods t tid -- ^ Table methods to lookup values by /tid/. |
520 | -> (g -> (tid,g)) -- ^ Generate a new unique /tid/ value and update the generator state /g/. | 533 | -> (g -> (tid,g)) -- ^ Generate a new unique /tid/ value and update the generator state /g/. |
521 | -> TransactionMethods (g,t (Maybe x -> IO ())) tid addr x | 534 | -> TransactionMethods (g,t (Result x -> IO ())) tid addr x |
522 | transactionMethods methods generate = transactionMethods' id id methods generate | 535 | transactionMethods methods generate = transactionMethods' id id methods generate |
523 | 536 | ||
524 | -- | Handle a single inbound packet and then invoke the given continuation. | 537 | -- | Handle a single inbound packet and then invoke the given continuation. |