tristanable/source/tristanable/watcher.d

107 lines
2.2 KiB
D
Raw Normal View History

2020-09-29 18:13:36 +01:00
module tristanable.watcher;
2020-09-29 10:57:25 +01:00
2020-09-29 18:18:53 +01:00
import std.socket : Socket;
import core.sync.mutex : Mutex;
import bmessage : receiveMessage;
import tristanable.queue : Queue;
import tristanable.queueitem : QueueItem;
import tristanable.manager : Manager;
import core.thread : Thread;
import tristanable.encoding;
2021-09-08 19:24:45 +01:00
import tristanable.exceptions;
2020-09-29 18:18:53 +01:00
2020-09-29 10:57:25 +01:00
public final class Watcher : Thread
{
2020-09-29 18:13:36 +01:00
/* The manager */
private Manager manager;
/* The socket to read from */
private Socket socket;
2021-09-08 19:24:45 +01:00
private bool running;
2021-09-08 10:19:05 +01:00
2020-09-29 18:13:36 +01:00
this(Manager manager, Socket endpoint)
2020-09-29 10:57:25 +01:00
{
2020-09-29 18:13:36 +01:00
super(&run);
this.manager = manager;
socket = endpoint;
2020-10-16 16:11:32 +01:00
2021-09-08 19:54:34 +01:00
running = true;
2020-10-16 16:11:32 +01:00
start();
2020-09-29 10:57:25 +01:00
}
2021-09-08 10:19:05 +01:00
public void shutdown()
{
2021-09-08 19:24:45 +01:00
running=false;
2021-09-08 10:19:05 +01:00
/* Close the socket, causing an error, breaking the event loop */
socket.close();
2021-09-08 19:24:45 +01:00
2021-09-08 10:19:05 +01:00
}
2020-09-29 10:57:25 +01:00
private void run()
{
/* Continuously dequeue tristanable packets from socket */
while(true)
{
/* Receive payload (tag+data) */
byte[] receivedPayload;
/* Block for socket response */
2020-09-29 18:18:53 +01:00
bool recvStatus = receiveMessage(socket, receivedPayload);
2020-09-29 10:57:25 +01:00
/* If the receive was successful */
if(recvStatus)
{
/* Decode the ttag-encoded message */
DataMessage message = DataMessage.decode(receivedPayload);
2020-09-29 18:13:36 +01:00
/* TODO: Remove isTag, improve later, oneshot */
/* The matching queue (if any) */
Queue queue = manager.getQueue(message.getTag());
/* If the tag belongs to a queue */
if(queue)
{
/* Add an item to this queue */
queue.enqueue(new QueueItem(message.getData()));
}
/* If the tag is unknwon */
else
{
/* TODO: Add to dropped queue? */
2020-09-29 10:57:25 +01:00
2020-09-29 18:13:36 +01:00
/* Do nothing */
}
2020-09-29 10:57:25 +01:00
}
/* If the receive failed */
else
{
2021-09-08 19:24:45 +01:00
/* TODO: depending on `running`, different error */
2020-09-29 10:57:25 +01:00
/* TODO: Stop everything */
break;
}
/**
* Like in `dequeue` we don't want the possibility
* of racing back to the top of the loop and locking
* the mutex again right before a thread switch,
* so we make sure that a switch occurs to a different
* thread
*/
Thread.getThis().yield();
}
2021-09-08 19:24:45 +01:00
/* Check if we had an error */
if(running)
{
throw new TristanableException(manager, "bformat socket error");
}
else
{
/* Actual shut down, do nothing */
}
2020-09-29 10:57:25 +01:00
}
}