1 /**
2  * Protocol interfaces.
3  */
4 module asynchronous.protocols;
5 
6 import asynchronous.transports;
7 
8 /**
9  * Common interface for protocol interfaces.
10  *
11  * Usually user implements protocols that derived from BaseProtocol like
12  * Protocol or ProcessProtocol.
13  *
14  * The only case when BaseProtocol should be implemented directly is write-only
15  * transport like write pipe
16  */
17 interface BaseProtocol
18 {
19     // Connection callbacks
20     /**
21      * $(D_PSYMBOL connectionMade()) and $(D_PSYMBOL connectionLost()) are
22      * called exactly once per successful connection. All other callbacks will
23      * be called between those two methods, which allows for easier resource
24      * management in your protocol implementation.
25      */
26 
27     /**
28      * Called when a connection is made.
29      *
30      * Params:
31      *  transport = is the transport representing the connection. You are
32      *      responsible for storing it somewhere if you need to.
33      */
34     void connectionMade(BaseTransport transport);
35 
36     /**
37      * Called when the connection is lost or closed.
38      *
39      * Params:
40      *  exception = is either an exception object or $(D_KEYWORD null). The
41      *      latter means a regular EOF is received, or the connection was
42      *      aborted or closed by this side of the connection.
43      */
44     void connectionLost(Exception exception);
45 
46     // Flow control callbacks
47     /**
48      * $(D_PSYMBOL pauseWriting()) and $(D_PSYMBOL resumeWriting()) calls are
49      * paired – $(D_PSYMBOL pauseWriting()) is called once when the buffer goes
50      * strictly over the high-water mark (even if subsequent writes increases
51      * the buffer size even more), and eventually $(D_PSYMBOL resumeWriting())
52      * is called once when the buffer size reaches the low-water mark.
53      */
54 
55     /**
56      * Called when the transport’s buffer goes over the high-water mark.
57      */
58     void pauseWriting();
59 
60     /**
61      * Called when the transport’s buffer drains below the low-water mark.
62      */
63     void resumeWriting();
64 }
65 
66 alias ProtocolFactory = Protocol delegate();
67 
68 /**
69  * Interface for stream protocol.
70  */
71 interface Protocol : BaseProtocol
72 {
73     /**
74      * Called when some data is received.
75      *
76      * Params:
77      *  data = is a non-empty array containing the incoming data.
78      */
79     void dataReceived(const(void)[] data);
80 
81     /**
82      * Calls when the other end signals it won’t send any more data (for example
83      * by calling $(D_PSYMBOL writeEof()), if the other end also uses
84      * asynchronous IO).
85      *
86      * This method may return a $(D_KEYWORD false) value, in which case the
87      * transport will close itself. Conversely, if this method returns a
88      * $(D_KEYWORD true) value, closing the transport is up to the protocol.
89      */
90     bool eofReceived();
91 
92     /**
93      * $(D_PSYMBOL dataReceived()) can be called an arbitrary number of times
94      * during a connection. However, $(D_PSYMBOL eofReceived()) is called at
95      * most once and, if called, $(D_PSYMBOL dataReceived()) won’t be called
96      * after it.
97      */
98 }
99 
100 alias DatagramProtocolFactory = DatagramProtocol delegate();
101 
102 /**
103  * Interface for datagram protocol.
104  */
105 interface DatagramProtocol : BaseProtocol
106 {
107     /**
108      * Called when a datagram is received.
109      *
110      * Params:
111      *  data = is an array containing the incoming data.
112      *  address = is the address of the peer sending the data; the exact format
113      *            depends on the transport.
114      */
115     void datagramReceived(const(void)[] data, Address address);
116 
117     /**
118      * Called when a previous send or receive operation raises an exception.
119      *
120      * Params:
121      *  exception = is the exception instance.
122      *
123      * This method is called in rare conditions, when the transport (e.g. UDP)
124      * detects that a datagram couldn’t be delivered to its recipient. In many
125      * conditions though, undeliverable datagrams will be silently dropped.
126      */
127     void errorReceived(Exception exception);
128 }
129 
130 /**
131  * Interface for protocol for subprocess calls.
132  */
133 interface SubprocessProtocol : BaseProtocol
134 {
135     /**
136      * Called when the child process writes data into its stdout or stderr pipe.
137      *
138      * Params:
139      *  fd = is the file descriptor of the pipe.
140      *
141      *  data = is a non-empty array containing the data.
142      */
143     void pipeDataReceived(int fd, const(void)[] data);
144 
145     /**
146      * Called when one of the pipes communicating with the child process is
147      * closed.
148      *
149      * Params:
150      *  fd = is the file descriptor that was closed.
151      *
152      *  exception = is either an exception object or $(D_KEYWORD null). The
153      *      latter means a regular EOF is received, or the connection was
154      *      aborted or closed by this side of the connection.
155      */
156     void pipeConnectionLost(int fd, Exception exception);
157 
158     /**
159      * Called when the child process has exited.
160      */
161     void processExited();
162 }