diff options
-rw-r--r-- | TODO.org | 4 | ||||
-rw-r--r-- | src/Remote/KRPC.hs | 28 |
2 files changed, 21 insertions, 11 deletions
@@ -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 | |||
125 | import Data.Monoid | 126 | import Data.Monoid |
126 | import Data.Typeable | 127 | import Data.Typeable |
127 | import Network | 128 | import Network |
128 | |||
129 | import GHC.Generics | 129 | import GHC.Generics |
130 | 130 | ||
131 | import Remote.KRPC.Protocol | 131 | import 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 | ||
308 | type HandlerBody remote = KQuery -> remote (Either KError KResponse) | 308 | type HandlerBody remote = KRemoteAddr -> KQuery -> remote (Either KError KResponse) |
309 | 309 | ||
310 | -- | Procedure signature and implementation binded up. | 310 | -- | Procedure signature and implementation binded up. |
311 | type MethodHandler remote = (MethodName, HandlerBody remote) | 311 | type 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 (==>) #-} |
322 | m ==> body = (methodName m, newbody) | 322 | m ==> body = m ==>@ const body |
323 | infix 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 (==>@) #-} | ||
333 | m ==>@ 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 | ||
332 | infix 1 ==> | 343 | infix 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 () |
344 | server servport handlers = do | 355 | server 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 | ||