1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
-- |
-- Copyright : (c) Sam Truzjan 2013
-- License : BSD3
-- Maintainer : pxqr.sta@gmail.com
-- Stability : experimental
-- Portability : portable
--
-- This module provides safe remote procedure call. One important
-- point is exceptions and errors, so to be able handle them
-- properly we need to investigate a bit about how this all works.
-- Internally, in order to make method invokation KRPC makes the
-- following steps:
--
-- * Caller serialize arguments to bencoded bytestrings;
--
-- * Caller send bytestring data over UDP to the callee;
--
-- * Callee receive and decode arguments to the method and method
-- name. If it can't decode then it send 'ProtocolError' back to the
-- caller;
--
-- * Callee search for the @method name@ in the method table.
-- If it not present in the table then callee send 'MethodUnknown'
-- back to the caller;
--
-- * Callee check if argument names match. If not it send
-- 'ProtocolError' back;
--
-- * Callee make the actuall call to the plain old haskell
-- function. If the function throw exception then callee send
-- 'ServerError' back.
--
-- * Callee serialize result of the function to bencoded bytestring.
--
-- * Callee encode result to bencoded bytestring and send it back
-- to the caller.
--
-- * Caller check if return values names match with the signature
-- it called in the first step.
--
-- * Caller extracts results and finally return results of the
-- procedure call as ordinary haskell values.
--
-- If every other error occurred then caller get the
-- 'GenericError'. All errors returned by callee are throwed as
-- ordinary haskell exceptions at caller side. Also note that both
-- caller and callee use plain UDP, so KRPC is unreliable.
--
-- For async 'query' use @async@ package.
--
-- For protocol details see "Network.KRPC.Message" module.
--
module Network.KRPC
( -- * Methods
Method
, KRPC (..)
-- * RPC
-- ** Query
, QueryFailure (..)
, query
, getQueryCount
-- ** Handler
, HandlerFailure (..)
, Handler
, handler
-- * Manager
, MonadKRPC (..)
, Options (..)
, def
, Manager
, newManager
, closeManager
, withManager
, listen
-- * Re-expor
, ErrorCode (..)
, SockAddr (..)
) where
import Data.Default.Class
import Network.KRPC.Message
import Network.KRPC.Method
import Network.KRPC.Manager
import Network.Socket (SockAddr (..))
|