summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.org4
-rw-r--r--src/Remote/KRPC.hs28
2 files changed, 21 insertions, 11 deletions
diff --git a/TODO.org b/TODO.org
index fa2df33c..9bbf5683 100644
--- a/TODO.org
+++ b/TODO.org
@@ -11,5 +11,5 @@
11* DONE add Show instance for Method 11* DONE add Show instance for Method
12* DONE add BEncodable instance for Method 12* DONE add BEncodable instance for Method
13* DONE remove async api 13* DONE remove async api
14* TODO expose client addr in server-side handlers 14* DONE expose client addr in server-side handlers
15* TODO major version bump (reason: exported type changed) 15* TODO major version bump to 0.2.0.0 (reason: async API removed)
diff --git a/src/Remote/KRPC.hs b/src/Remote/KRPC.hs
index ab989782..be5673d8 100644
--- a/src/Remote/KRPC.hs
+++ b/src/Remote/KRPC.hs
@@ -107,6 +107,7 @@ module Remote.KRPC
107 -- * Server 107 -- * Server
108 , MethodHandler 108 , MethodHandler
109 , (==>) 109 , (==>)
110 , (==>@)
110 , server 111 , server
111 112
112 -- * Internal 113 -- * Internal
@@ -125,7 +126,6 @@ import Data.Map as M
125import Data.Monoid 126import Data.Monoid
126import Data.Typeable 127import Data.Typeable
127import Network 128import Network
128
129import GHC.Generics 129import GHC.Generics
130 130
131import Remote.KRPC.Protocol 131import Remote.KRPC.Protocol
@@ -305,7 +305,7 @@ call_ sock addr m arg = liftIO $ do
305 getResult sock m 305 getResult sock m
306 306
307 307
308type HandlerBody remote = KQuery -> remote (Either KError KResponse) 308type HandlerBody remote = KRemoteAddr -> KQuery -> remote (Either KError KResponse)
309 309
310-- | Procedure signature and implementation binded up. 310-- | Procedure signature and implementation binded up.
311type MethodHandler remote = (MethodName, HandlerBody remote) 311type MethodHandler remote = (MethodName, HandlerBody remote)
@@ -319,17 +319,28 @@ type MethodHandler remote = (MethodName, HandlerBody remote)
319 -> (param -> remote result) -- ^ Implementation. 319 -> (param -> remote result) -- ^ Implementation.
320 -> MethodHandler remote -- ^ Handler used by server. 320 -> MethodHandler remote -- ^ Handler used by server.
321{-# INLINE (==>) #-} 321{-# INLINE (==>) #-}
322m ==> body = (methodName m, newbody) 322m ==> body = m ==>@ const body
323infix 1 ==>
324
325-- | Similar to '==>@' but additionally pass caller address.
326(==>@) :: forall (remote :: * -> *) (param :: *) (result :: *).
327 (BEncodable param, BEncodable result)
328 => Monad remote
329 => Method param result -- ^ Signature.
330 -> (KRemoteAddr -> param -> remote result) -- ^ Implementation.
331 -> MethodHandler remote -- ^ Handler used by server.
332{-# INLINE (==>@) #-}
333m ==>@ body = (methodName m, newbody)
323 where 334 where
324 {-# INLINE newbody #-} 335 {-# INLINE newbody #-}
325 newbody q = 336 newbody addr q =
326 case fromBEncode =<< extractArgs (methodParams m) (queryArgs q) of 337 case fromBEncode =<< extractArgs (methodParams m) (queryArgs q) of
327 Left e -> return (Left (ProtocolError (BC.pack e))) 338 Left e -> return (Left (ProtocolError (BC.pack e)))
328 Right a -> do 339 Right a -> do
329 r <- body a 340 r <- body addr a
330 return (Right (kresponse (injectVals (methodVals m) (toBEncode r)))) 341 return (Right (kresponse (injectVals (methodVals m) (toBEncode r))))
331 342
332infix 1 ==> 343infix 1 ==>@
333 344
334-- TODO: allow forkIO 345-- TODO: allow forkIO
335 346
@@ -342,11 +353,10 @@ server :: (MonadBaseControl IO remote, MonadIO remote)
342 -> [MethodHandler remote] -- ^ Method table. 353 -> [MethodHandler remote] -- ^ Method table.
343 -> remote () 354 -> remote ()
344server servport handlers = do 355server servport handlers = do
345 remoteServer servport $ \_ q -> do 356 remoteServer servport $ \addr q -> do
346 case dispatch (queryMethod q) of 357 case dispatch (queryMethod q) of
347 Nothing -> return $ Left $ MethodUnknown (queryMethod q) 358 Nothing -> return $ Left $ MethodUnknown (queryMethod q)
348 Just m -> invoke m q 359 Just m -> m addr q
349 where 360 where
350 handlerMap = M.fromList handlers 361 handlerMap = M.fromList handlers
351 dispatch s = M.lookup s handlerMap 362 dispatch s = M.lookup s handlerMap
352 invoke m q = m q