summaryrefslogtreecommitdiff
path: root/src/Network/QueryResponse.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/QueryResponse.hs')
-rw-r--r--src/Network/QueryResponse.hs47
1 files changed, 19 insertions, 28 deletions
diff --git a/src/Network/QueryResponse.hs b/src/Network/QueryResponse.hs
index 0fa1a05a..70d981e2 100644
--- a/src/Network/QueryResponse.hs
+++ b/src/Network/QueryResponse.hs
@@ -108,18 +108,18 @@ partitionTransportM parse encodex tr = do
108 } 108 }
109 return (xtr, ytr) 109 return (xtr, ytr)
110 110
111addHandler :: (addr -> x -> IO (Maybe (x -> x))) -> Transport err addr x -> Transport err addr x 111addHandler :: ErrorReporter addr x meth tid err -> (addr -> x -> IO (Maybe (x -> x))) -> Transport err addr x -> Transport err addr x
112addHandler f tr = tr 112addHandler err f tr = tr
113 { awaitMessage = \kont -> fix $ \eat -> awaitMessage tr $ \m -> do 113 { awaitMessage = \kont -> fix $ \eat -> awaitMessage tr $ \m -> do
114 case m of 114 case m of
115 Just (Right (x, addr)) -> f addr x >>= maybe eat (kont . Just . Right . (, addr) . ($ x)) 115 Just (Right (x, addr)) -> f addr x >>= maybe eat (kont . Just . Right . (, addr) . ($ x))
116 Just (Left e ) -> kont $ Just (Left e) 116 Just (Left e ) -> reportParseError err e >> kont (Just $ Left e)
117 Nothing -> kont $ Nothing 117 Nothing -> kont $ Nothing
118 } 118 }
119 119
120-- | Modify a 'Transport' to invoke an action upon every received packet. 120-- | Modify a 'Transport' to invoke an action upon every received packet.
121onInbound :: (addr -> x -> IO ()) -> Transport err addr x -> Transport err addr x 121onInbound :: (addr -> x -> IO ()) -> Transport err addr x -> Transport err addr x
122onInbound f tr = addHandler (\addr x -> f addr x >> return (Just id)) tr 122onInbound f tr = addHandler ignoreErrors (\addr x -> f addr x >> return (Just id)) tr
123 123
124-- * Using a query\/response client. 124-- * Using a query\/response client.
125 125
@@ -153,16 +153,17 @@ sendQuery ::
153 -> a -- ^ The outbound query. 153 -> a -- ^ The outbound query.
154 -> addr -- ^ Destination address of query. 154 -> addr -- ^ Destination address of query.
155 -> IO (Maybe b) -- ^ The response, or 'Nothing' if it timed out. 155 -> IO (Maybe b) -- ^ The response, or 'Nothing' if it timed out.
156sendQuery (Client net d err pending whoami _) meth q addr = do 156sendQuery (Client net d err pending whoami _) meth q addr0 = do
157 mvar <- newEmptyMVar 157 mvar <- newEmptyMVar
158 tid <- atomically $ do 158 (tid,addr,expiry) <- atomically $ do
159 tbl <- readTVar pending 159 tbl <- readTVar pending
160 (tid, tbl') <- dispatchRegister (tableMethods d) mvar tbl 160 (tid, tbl') <- dispatchRegister (tableMethods d) mvar addr0 tbl
161 (addr,expiry) <- methodTimeout meth tid addr0
161 writeTVar pending tbl' 162 writeTVar pending tbl'
162 return tid 163 return (tid,addr,expiry)
163 self <- whoami (Just addr) 164 self <- whoami (Just addr)
164 sendMessage net addr (wrapQuery meth tid self addr q) 165 sendMessage net addr (wrapQuery meth tid self addr q)
165 mres <- timeout (1000000 * methodTimeout meth) $ takeMVar mvar 166 mres <- timeout expiry $ takeMVar mvar
166 case mres of 167 case mres of
167 Just x -> return $ Just $ unwrapResponse meth x 168 Just x -> return $ Just $ unwrapResponse meth x
168 Nothing -> do 169 Nothing -> do
@@ -248,8 +249,10 @@ dispatchQuery (NoReply unwrapQ f) tid self x addr =
248-- peer-to-peer algorithm will define a 'MethodSerializer' for every 'MethodHandler' that 249-- peer-to-peer algorithm will define a 'MethodSerializer' for every 'MethodHandler' that
249-- might be returned by 'lookupHandler'. 250-- might be returned by 'lookupHandler'.
250data MethodSerializer tid addr x meth a b = MethodSerializer 251data MethodSerializer tid addr x meth a b = MethodSerializer
251 { -- | Seconds to wait for a response. 252 { -- | Returns the microseconds to wait for a response to this query being
252 methodTimeout :: Int 253 -- sent to the given address. The /addr/ may also be modified to add
254 -- routing information.
255 methodTimeout :: tid -> addr -> STM (addr,Int)
253 -- | A method identifier used for error reporting. This needn't be the 256 -- | A method identifier used for error reporting. This needn't be the
254 -- same as the /meth/ argument to 'MethodHandler', but it is suggested. 257 -- same as the /meth/ argument to 'MethodHandler', but it is suggested.
255 , method :: meth 258 , method :: meth
@@ -269,13 +272,13 @@ data MethodSerializer tid addr x meth a b = MethodSerializer
269-- 272--
270-- The type variable /d/ is used to represent the current state of the 273-- The type variable /d/ is used to represent the current state of the
271-- transaction generator and the table of pending transactions. 274-- transaction generator and the table of pending transactions.
272data TransactionMethods d tid x = TransactionMethods 275data TransactionMethods d tid addr x = TransactionMethods
273 { 276 {
274 -- | Before a query is sent, this function stores an 'MVar' to which the 277 -- | Before a query is sent, this function stores an 'MVar' to which the
275 -- response will be written too. The returned /tid/ is a transaction id 278 -- response will be written too. The returned /tid/ is a transaction id
276 -- that can be used to forget the 'MVar' if the remote peer is not 279 -- that can be used to forget the 'MVar' if the remote peer is not
277 -- responding. 280 -- responding.
278 dispatchRegister :: MVar x -> d -> STM (tid, d) 281 dispatchRegister :: MVar x -> addr -> d -> STM (tid, d)
279 -- | This method is invoked when an incoming packet /x/ indicates it is 282 -- | This method is invoked when an incoming packet /x/ indicates it is
280 -- a response to the transaction with id /tid/. The returned IO action 283 -- a response to the transaction with id /tid/. The returned IO action
281 -- is will write the packet to the correct 'MVar' thus completing the 284 -- is will write the packet to the correct 'MVar' thus completing the
@@ -318,27 +321,15 @@ instance Contravariant (TableMethods t) where
318 (\k t -> del (f k) t) 321 (\k t -> del (f k) t)
319 (\k t -> lookup (f k) t) 322 (\k t -> lookup (f k) t)
320 323
321-- | Since 'Int' may be 32 or 64 bits, this function is provided as a
322-- convenience to test if an integral type, such as 'Data.Word.Word64', can be
323-- safely transformed into an 'Int' for use with 'IntMap'.
324--
325-- Returns 'True' if the proxied type can be losslessly converted to 'Int' using
326-- 'fromIntegral'.
327fitsInInt :: forall word. (Bounded word, Integral word) => Proxy word -> Bool
328fitsInInt Proxy = (original == casted)
329 where
330 original = div maxBound 2 :: word
331 casted = fromIntegral (fromIntegral original :: Int) :: word
332
333-- | Construct 'TransactionMethods' methods out of 3 lookup table primitives and a 324-- | Construct 'TransactionMethods' methods out of 3 lookup table primitives and a
334-- function for generating unique transaction ids. 325-- function for generating unique transaction ids.
335transactionMethods :: 326transactionMethods ::
336 TableMethods t tid -- ^ Table methods to lookup values by /tid/. 327 TableMethods t tid -- ^ Table methods to lookup values by /tid/.
337 -> (g -> (tid,g)) -- ^ Generate a new unique /tid/ value and update the generator state /g/. 328 -> (g -> (tid,g)) -- ^ Generate a new unique /tid/ value and update the generator state /g/.
338 -> TransactionMethods (g,t (MVar x)) tid x 329 -> TransactionMethods (g,t (MVar x)) tid addr x
339transactionMethods (TableMethods insert delete lookup) generate = TransactionMethods 330transactionMethods (TableMethods insert delete lookup) generate = TransactionMethods
340 { dispatchCancel = \tid (g,t) -> return (g, delete tid t) 331 { dispatchCancel = \tid (g,t) -> return (g, delete tid t)
341 , dispatchRegister = \v (g,t) -> 332 , dispatchRegister = \v _ (g,t) ->
342 let (tid,g') = generate g 333 let (tid,g') = generate g
343 t' = insert tid v t 334 t' = insert tid v t
344 in return ( tid, (g',t') ) 335 in return ( tid, (g',t') )
@@ -356,7 +347,7 @@ data DispatchMethods tbl err meth tid addr x = DispatchMethods
356 -- | Lookup the handler for a inbound query. 347 -- | Lookup the handler for a inbound query.
357 , lookupHandler :: meth -> Maybe (MethodHandler err tid addr x) 348 , lookupHandler :: meth -> Maybe (MethodHandler err tid addr x)
358 -- | Methods for handling incoming responses. 349 -- | Methods for handling incoming responses.
359 , tableMethods :: TransactionMethods tbl tid x 350 , tableMethods :: TransactionMethods tbl tid addr x
360 } 351 }
361 352
362-- | These methods indicate what should be done upon various conditions. Write 353-- | These methods indicate what should be done upon various conditions. Write