All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.lucaventuri.fibry.distributed.MessageHolder Maven / Gradle / Ivy

There is a newer version: 3.0.1
Show newest version
package eu.lucaventuri.fibry.distributed;

import eu.lucaventuri.common.NetworkUtils;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.SocketChannel;
import java.util.concurrent.CompletableFuture;

class MessageHolder {
    private final String message;
    private final MessageType type;
    private final long answerId;

    enum MessageType {
        WITH_RETURN((byte) 'R'), VOID((byte) 'V'), ANSWER((byte) 'A'), EXCEPTION((byte) 'E');

        final byte signature;

        MessageType(byte signature) {
            this.signature = signature;
        }

        static MessageType fromSignature(byte signature) {
            for (var value : values()) {
                if (value.signature == signature)
                    return value;
            }

            throw new IllegalArgumentException("Unrecognized MessageType signature " + signature);
        }
    }

    private MessageHolder(String message, MessageType type, long answerId) {
        this.message = message;
        this.type = type;
        this.answerId = answerId;
    }

    CompletableFuture writeMessage(SocketChannel ch, MessageRegistry msgReg) throws IOException {
        final CompletableFuture future;
        if (type == MessageType.WITH_RETURN) {
            var buf = ByteBuffer.allocate(9);
            var idAndFuture = msgReg.getNewFuture();

            //System.out.println("writeMessage(): " + message + " - New " + idAndFuture.id);

            buf.order(ByteOrder.BIG_ENDIAN);
            buf.put(type.signature);
            buf.putLong(idAndFuture.id);
            buf.flip();

            ch.write(buf);

            future = idAndFuture.future;
        } else if (type == MessageType.VOID) {
            ch.write(ByteBuffer.wrap(new byte[]{type.signature}));
            // TODO: it does not wait for the messge to be processed. Id it fine?
            future = null;
        } else if (type == MessageType.ANSWER) {
            var buf = ByteBuffer.allocate(9);

            buf.order(ByteOrder.BIG_ENDIAN);
            buf.put(type.signature);
            buf.putLong(answerId);
            buf.flip();

            ch.write(buf);
            future = null;
        } else if (type == MessageType.EXCEPTION) {
            var buf = ByteBuffer.allocate(9);

            buf.order(ByteOrder.BIG_ENDIAN);
            buf.put(type.signature);
            buf.putLong(answerId);
            buf.flip();

            ch.write(buf);
            future = null;
        } else
            throw new IllegalStateException("Unexpected MessageType " + type);

        ch.write(NetworkUtils.asBufferWithLength32(message));

        return future;
    }

    @Override
    public String toString() {
        return "MessageHolder{" +
                "message='" + message + '\'' +
                ", type=" + type +
                '}';
    }

    static  MessageHolder newWithReturn(String message) {
        return new MessageHolder(message, MessageType.WITH_RETURN, 0);
    }

    static  MessageHolder newVoid(String message) {
        return new MessageHolder(message, MessageType.VOID, 0);
    }

    static  MessageHolder newAnswer(long messageId, String message) {
        return new MessageHolder(message, MessageType.ANSWER, messageId);
    }

    static  MessageHolder newException(long messageId, Throwable ex) {
        return new MessageHolder(ex.toString(), MessageType.EXCEPTION, messageId);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy