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

io.reacted.drivers.channels.chroniclequeue.CQRemoteDriver Maven / Gradle / Ivy

There is a newer version: 2.1.4
Show newest version
/*
 * Copyright (c) 2020 ,  [ [email protected] ]
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree.
 */

package io.reacted.drivers.channels.chroniclequeue;

import io.reacted.core.config.ChannelId;
import io.reacted.core.drivers.system.RemotingDriver;
import io.reacted.core.messages.Message;
import io.reacted.core.messages.reactors.DeliveryStatus;
import io.reacted.core.reactorsystem.ReActorContext;
import io.reacted.core.reactorsystem.ReActorSystem;
import io.reacted.patterns.NonNullByDefault;
import io.reacted.patterns.Try;
import io.reacted.patterns.UnChecked;
import java.util.Objects;
import java.util.Properties;
import java.util.concurrent.CompletableFuture;
import javax.annotation.Nullable;
import net.openhft.chronicle.queue.ChronicleQueue;
import net.openhft.chronicle.queue.ExcerptAppender;
import net.openhft.chronicle.queue.ExcerptTailer;
import net.openhft.chronicle.threads.Pauser;
import net.openhft.chronicle.wire.DocumentContext;
import net.openhft.chronicle.wire.WireKey;

@NonNullByDefault
public class CQRemoteDriver extends RemotingDriver {
    @Nullable
    private ChronicleQueue chronicle;
    @Nullable
    private ExcerptTailer cqTailer;

    public CQRemoteDriver(CQDriverConfig driverConfig) {
        super(driverConfig);
    }

    @Override
    public void initDriverLoop(ReActorSystem reActorSystem) {
        this.chronicle = ChronicleQueue.singleBuilder(getDriverConfig().getChronicleFilesDir()).build();
        this.cqTailer = chronicle.createTailer().toEnd();
    }

    @Override
    public boolean equals(@Nullable Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        if (!super.equals(o)) return false;
        CQRemoteDriver that = (CQRemoteDriver) o;
        return Objects.equals(getDriverConfig(), that.getDriverConfig());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getDriverConfig());
    }

    @Override
    public UnChecked.CheckedRunnable getDriverLoop() {
        return () -> cqRemoteDriverMainLoop(Objects.requireNonNull(cqTailer), Objects.requireNonNull(chronicle));
    }

    @Override
    public CompletableFuture> cleanDriverLoop() {
        return CompletableFuture.completedFuture(Try.ofRunnable(() -> Objects.requireNonNull(chronicle).close()));
    }

    @Override
    public ChannelId getChannelId() {
        return ChannelId.ChannelType.REMOTING_CHRONICLE_QUEUE.forChannelName(getDriverConfig().getChannelName());
    }

    @Override
    public Properties getChannelProperties() { return getDriverConfig().getProperties(); }

    @Override
    public DeliveryStatus sendMessage(ReActorContext destination, Message message) {
        return sendMessage(getLocalReActorSystem(),
                           Objects.requireNonNull(chronicle)
                                  .acquireAppender(), getDriverConfig().getTopic(), message);
    }

    private void cqRemoteDriverMainLoop(ExcerptTailer cqTailer, ChronicleQueue chronicle) {
        Pauser readPauser = Pauser.balanced();

        while (!Thread.currentThread().isInterrupted() && !chronicle.isClosed()) {

            Message newMessage = null;
            try(DocumentContext docCtx = cqTailer.readingDocument()) {
                if (docCtx.isPresent()) {
                    newMessage = docCtx.wire().read(getDriverConfig().getTopic())
                                       .object(Message.class);
                    readPauser.reset();
                }
            } catch (Exception anyException) {
                getLocalReActorSystem().logError("Unable to properly decode message", anyException);
            }

            if (newMessage == null) {
                readPauser.pause();
                continue;
            }

            offerMessage(newMessage);
        }
    }
    private static DeliveryStatus sendMessage(ReActorSystem localReActorSystem,
                                              ExcerptAppender cqAppender, WireKey topic,  Message message) {
        try {
            cqAppender.writeMessage(topic, message);
            return DeliveryStatus.SENT;
        } catch (Exception sendError) {
            localReActorSystem.logError("Error sending message {}", message.toString(),
                                        sendError);
            return DeliveryStatus.NOT_SENT;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy