besterd/source/server/informer/informer.d

83 lines
2.2 KiB
D

module server.informer.informer;
import core.thread : Thread;
import server.server : BesterServer;
import std.socket;
import server.informer.client : BesterInformerClient;
/**
* The `BesterInformer` allows handlers to query (out-of-band)
* information regarding this bester server.
*
* This is useful when the message handler requires additional
* information before it sends its final message response.
*/
public final class BesterInformer : Thread
{
/* The associated `BesterServer` */
private BesterServer server;
/* Informer socket */
private Socket informerSocket;
/* Whether or not the informer server is active */
private bool active = true;
/* Connected clients */
private BesterInformerClient[] informerClients;
/**
* Constructs a new `BesterInformer` object
* which will accept incoming connections
* (upon calling `.start`) from handlers,
* over a UNIX domain socket, requesting
* server information.
*/
this(BesterServer server)
{
/* Set the worker function */
super(&worker);
/* Setup the socket */
informerSocket = new Socket(AddressFamily.UNIX, SocketType.STREAM);
informerSocket.bind(new UnixAddress("bInformer"));
informerSocket.listen(1); /* TODO: Value */
/* Set the associated BesterServer */
this.server = server;
}
/**
* Client send-receive loop.
* Accepts incoming connections to the informer
* and dispatches them to a worker thread.
*/
private void worker()
{
while(active)
{
/* Accept the queued incoming connection */
Socket handlerSocket = informerSocket.accept();
/**
* Create a new worker for the informer client, adds it
* to the client queue and dispatches its worker thread.
*/
BesterInformerClient newInformer = new BesterInformerClient(server, handlerSocket);
informerClients ~= newInformer;
newInformer.start();
}
/* Close the informer socket */
informerSocket.close();
}
public void shutdown()
{
for(ulong i = 0; i < informerClients.length; i++)
{
informerClients[i].shutdown();
}
}
}