@@ -0,0 +1,3088 @@
+package com.jenjinstudios.io.connection;%0A%0Aimport com.jenjinstudios.io.ExecutionContext;%0Aimport com.jenjinstudios.io.MessageReader;%0Aimport com.jenjinstudios.io.MessageWriter;%0Aimport com.jenjinstudios.io.concurrency.*;%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0Aimport java.io.IOException;%0Aimport java.util.concurrent.Executors;%0Aimport java.util.concurrent.ScheduledExecutorService;%0Aimport java.util.concurrent.TimeUnit;%0A%0A/**%0A * Used for making connections so that Message objects can be read, written, and executed in a non-blocking fashion.%0A *%0A * @author Caleb Brinkman%0A */%0Apublic class Connection%0A%7B%0A    private static final Logger LOGGER = LoggerFactory.getLogger(Connection.class);%0A    private static final int TERMINATION_TIMEOUT = 120;%0A    private final ScheduledExecutorService executor;%0A    private final ExecutionContext context;%0A    private final MessageReader messageReader;%0A    private final MessageWriter messageWriter;%0A%0A    /**%0A     * Construct a new connection.%0A     *%0A     * @param context The context in which messages should execute.%0A     * @param messageReader The stream from which messages should be read.%0A     * @param messageWriter The stream to which messages should be written.%0A     */%0A    public Connection(%0A          ExecutionContext context,%0A          MessageReader messageReader,%0A          MessageWriter messageWriter)%0A    %7B%0A        executor = Executors.newScheduledThreadPool(4);%0A        this.context = context;%0A        this.messageReader = messageReader;%0A        this.messageWriter = messageWriter;%0A    %7D%0A%0A    /**%0A     * Start sending, receiving, and executing messages.%0A     */%0A    public void start() %7B%0A        MessageQueue messageQueue = new MessageQueue();%0A%0A        Runnable executionTask = new ExecutionTask(messageQueue, context);%0A        Runnable writeTask = new WriteTask(messageQueue, messageWriter);%0A        Runnable readTask = new ReadTask(messageQueue, messageReader);%0A        Runnable errorTask = new ErrorTask(messageQueue);%0A%0A        executor.scheduleWithFixedDelay(errorTask, 0, 10, TimeUnit.MILLISECONDS);%0A        executor.scheduleWithFixedDelay(readTask, 0, 10, TimeUnit.MILLISECONDS);%0A        executor.scheduleWithFixedDelay(writeTask, 0, 10, TimeUnit.MILLISECONDS);%0A        executor.scheduleWithFixedDelay(executionTask, 0, 10, TimeUnit.MILLISECONDS);%0A    %7D%0A%0A    /**%0A     * Stop sending, receiving, and executing messages, and close input and output streams.%0A     */%0A    public void stop() %7B%0A        LOGGER.debug(%22Shutting down executor service%22);%0A        executor.shutdown();%0A        try %7B%0A            executor.awaitTermination(TERMINATION_TIMEOUT, TimeUnit.SECONDS);%0A        %7D catch (InterruptedException e) %7B%0A            LOGGER.warn(%22Exception while awaiting executor shutdown%22, e);%0A        %7D%0A        try %7B%0A            messageReader.close();%0A        %7D catch (IOException e) %7B%0A            LOGGER.warn(%22Exception when closing input stream%22, e);%0A        %7D%0A        try %7B%0A            messageWriter.close();%0A        %7D catch (IOException e) %7B%0A            LOGGER.warn(%22Exception when closing output stream%22, e);%0A        %7D%0A    %7D%0A%7D%0A

Add Connection class