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 }