1 module butterflyd.handler;
2 
3 import std.socket : Socket, AddressFamily, SocketType, UnixAddress, SocketOSException, AddressException;
4 import butterflyd.exceptions : ButterflyException;
5 import butterflyd.client : ButterflyClient;
6 
7 /**
8 * Represents the message handler for the
9 * Bester server it is attached to (via
10 * a UNIX domain socket).
11 * This dispatches new connections from the
12 * server to that socket to client handlers
13 * that handle each connection from the Bester
14 * server wishing to get a handler response.
15 */
16 public final class ButterflyHandler
17 {
18     /* Bester handler socket */
19     private Socket handlerSocket;
20 
21     /**
22     * Constructs a new Butterfly message handler
23     * bound to the given UNIX domain socket path,
24     * `unixSocketPath` and starts listening.
25     *
26     * Throws a `ButterflyException` on any error
27     * regarding address format, binding or listening.
28     */
29     this(string unixSocketPath)
30     {
31         try
32         {
33             handlerSocket = new Socket(AddressFamily.UNIX, SocketType.STREAM);
34             handlerSocket.bind(new UnixAddress(unixSocketPath));
35             handlerSocket.listen(1); /* TODO: Value here */
36         }
37         catch(AddressException)
38         {
39             throw new ButterflyException("Address format incorrect");
40         }
41         catch(SocketOSException)
42         {
43             throw new ButterflyException("Error in setting up handler socket");
44         }
45     }
46 
47     /**
48     * Loops forever accepting new connections
49     * from the connection queue by dequeuing
50     * them, spawning a new `ButterflyClient`
51     * object and then starting its respective
52     * worker thread.
53     */
54     public void dispatcher()
55     {
56         bool isActive = true;
57         while(isActive)
58         {
59             /* Accept a connection from the backlog */
60             Socket connection = handlerSocket.accept();
61 
62             /* Spawn a new butterfly client */
63             ButterflyClient client = new ButterflyClient(connection);
64 
65             /* Start the thread */
66             client.start();
67         }
68     }
69 }