diff options
Diffstat (limited to 'src/Network/KRPC/Manager.hs')
-rw-r--r-- | src/Network/KRPC/Manager.hs | 43 |
1 files changed, 17 insertions, 26 deletions
diff --git a/src/Network/KRPC/Manager.hs b/src/Network/KRPC/Manager.hs index e7f0563b..b1e93101 100644 --- a/src/Network/KRPC/Manager.hs +++ b/src/Network/KRPC/Manager.hs | |||
@@ -76,6 +76,7 @@ import Data.Text as T | |||
76 | import Data.Text.Encoding as T | 76 | import Data.Text.Encoding as T |
77 | import Data.Tuple | 77 | import Data.Tuple |
78 | import Data.Typeable | 78 | import Data.Typeable |
79 | import Network.RPC | ||
79 | import Network.KRPC.Message | 80 | import Network.KRPC.Message |
80 | import Network.KRPC.Method | 81 | import Network.KRPC.Method |
81 | import Network.Socket hiding (listen) | 82 | import Network.Socket hiding (listen) |
@@ -136,11 +137,11 @@ type CallId = (TransactionId, SockAddr) | |||
136 | type CallRes = MVar (KQueryArgs, KResult) -- (raw response, decoded response) | 137 | type CallRes = MVar (KQueryArgs, KResult) -- (raw response, decoded response) |
137 | type PendingCalls = IORef (Map CallId CallRes) | 138 | type PendingCalls = IORef (Map CallId CallRes) |
138 | 139 | ||
139 | type HandlerBody h = SockAddr -> KQueryArgs -> h (Either String KQueryArgs) | 140 | type HandlerBody h msg v = SockAddr -> msg v -> h (Either String v) |
140 | 141 | ||
141 | -- | Handler is a function which will be invoked then some /remote/ | 142 | -- | Handler is a function which will be invoked then some /remote/ |
142 | -- node querying /this/ node. | 143 | -- node querying /this/ node. |
143 | type Handler h = (MethodName, HandlerBody h) | 144 | type Handler h msg v = (MethodName, HandlerBody h msg v) |
144 | 145 | ||
145 | -- | Keep track pending queries made by /this/ node and handle queries | 146 | -- | Keep track pending queries made by /this/ node and handle queries |
146 | -- made by /remote/ nodes. | 147 | -- made by /remote/ nodes. |
@@ -150,7 +151,7 @@ data Manager h = Manager | |||
150 | , listenerThread :: !(MVar ThreadId) | 151 | , listenerThread :: !(MVar ThreadId) |
151 | , transactionCounter :: {-# UNPACK #-} !TransactionCounter | 152 | , transactionCounter :: {-# UNPACK #-} !TransactionCounter |
152 | , pendingCalls :: {-# UNPACK #-} !PendingCalls | 153 | , pendingCalls :: {-# UNPACK #-} !PendingCalls |
153 | , handlers :: [Handler h] | 154 | , handlers :: [Handler h KMessageOf BValue] |
154 | } | 155 | } |
155 | 156 | ||
156 | -- | A monad which can perform or handle queries. | 157 | -- | A monad which can perform or handle queries. |
@@ -182,10 +183,10 @@ sockAddrFamily (SockAddrCan _ ) = AF_CAN | |||
182 | 183 | ||
183 | -- | Bind socket to the specified address. To enable query handling | 184 | -- | Bind socket to the specified address. To enable query handling |
184 | -- run 'listen'. | 185 | -- run 'listen'. |
185 | newManager :: Options -- ^ various protocol options; | 186 | newManager :: Options -- ^ various protocol options; |
186 | -> SockAddr -- ^ address to listen on; | 187 | -> SockAddr -- ^ address to listen on; |
187 | -> [Handler h] -- ^ handlers to run on incoming queries. | 188 | -> [Handler h KMessageOf BValue] -- ^ handlers to run on incoming queries. |
188 | -> IO (Manager h) -- ^ new rpc manager. | 189 | -> IO (Manager h) -- ^ new rpc manager. |
189 | newManager opts @ Options {..} servAddr handlers = do | 190 | newManager opts @ Options {..} servAddr handlers = do |
190 | validateOptions opts | 191 | validateOptions opts |
191 | sock <- bindServ | 192 | sock <- bindServ |
@@ -217,7 +218,7 @@ isActive Manager {..} = liftIO $ isBound sock | |||
217 | 218 | ||
218 | -- | Normally you should use Control.Monad.Trans.Resource.allocate | 219 | -- | Normally you should use Control.Monad.Trans.Resource.allocate |
219 | -- function. | 220 | -- function. |
220 | withManager :: Options -> SockAddr -> [Handler h] | 221 | withManager :: Options -> SockAddr -> [Handler h KMessageOf BValue] |
221 | -> (Manager h -> IO a) -> IO a | 222 | -> (Manager h -> IO a) -> IO a |
222 | withManager opts addr hs = bracket (newManager opts addr hs) closeManager | 223 | withManager opts addr hs = bracket (newManager opts addr hs) closeManager |
223 | 224 | ||
@@ -408,35 +409,25 @@ prettyQF e = T.encodeUtf8 $ "handler fail while performing query: " | |||
408 | -- If the handler make some 'query' normally it /should/ handle | 409 | -- If the handler make some 'query' normally it /should/ handle |
409 | -- corresponding 'QueryFailure's. | 410 | -- corresponding 'QueryFailure's. |
410 | -- | 411 | -- |
411 | handler :: forall h a b. (KRPC a b, Monad h) | 412 | handler :: forall h a b msg. (KRPC a b, Applicative h, Functor msg) |
412 | => (SockAddr -> a -> h b) -> Handler h | 413 | => Messaging msg TransactionId (Envelope a b) -> (SockAddr -> a -> h b) -> Handler h msg (Envelope a b) |
413 | handler body = (name, wrapper) | 414 | handler msging body = (name, wrapper) |
414 | where | 415 | where |
415 | Method name = method :: Method a b | 416 | Method name = method :: Method a b |
416 | wrapper addr args = | 417 | wrapper addr args = |
417 | #ifdef VERSION_bencoding | 418 | case unseal $ messagePayload msging args of |
418 | case fromBEncode args of | 419 | Left e -> pure $ Left e |
419 | #else | 420 | Right a -> Right . seal <$> body addr a |
420 | case S.decode args of | ||
421 | #endif | ||
422 | Left e -> return $ Left e | ||
423 | Right a -> do | ||
424 | r <- body addr a | ||
425 | #ifdef VERSION_bencoding | ||
426 | return $ Right $ toBEncode r | ||
427 | #else | ||
428 | return $ Right $ S.encode r | ||
429 | #endif | ||
430 | 421 | ||
431 | runHandler :: MonadKRPC h m | 422 | runHandler :: MonadKRPC h m |
432 | => HandlerBody h -> SockAddr -> KQuery -> m KResult | 423 | => HandlerBody h KMessageOf BValue -> SockAddr -> KQuery -> m KResult |
433 | runHandler h addr m = Lifted.catches wrapper failbacks | 424 | runHandler h addr m = Lifted.catches wrapper failbacks |
434 | where | 425 | where |
435 | signature = querySignature (queryMethod m) (queryId m) addr | 426 | signature = querySignature (queryMethod m) (queryId m) addr |
436 | 427 | ||
437 | wrapper = do | 428 | wrapper = do |
438 | $(logDebugS) "handler.quered" signature | 429 | $(logDebugS) "handler.quered" signature |
439 | result <- liftHandler (h addr (queryArgs m)) | 430 | result <- liftHandler (h addr (Q m)) |
440 | 431 | ||
441 | case result of | 432 | case result of |
442 | Left msg -> do | 433 | Left msg -> do |