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