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

net.tangly.fsm.actors.Channel Maven / Gradle / Ivy

/*
 * Copyright 2023-2024 Marcel Baumann
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 *          https://apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
 * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
 *
 */

package net.tangly.fsm.actors;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;

import java.util.concurrent.Flow;
import java.util.concurrent.SubmissionPublisher;

/**
 * Provide a subscription handler for multiple suppliers and consumers. The type of handled messages is a generic parameter and provides type security.
 * The implementation uses the flow interface of the standard Java API.
 * 

The channel provides the communication medium between publishers and subscribers. * Subscribers are asynchronous objects.

* * @param type of the messages handled by the channel */ public class Channel implements AutoCloseable { private final String name; private final SubmissionPublisher publisher; static class ActorSubscriber implements Flow.Subscriber { private static final Logger logger = LogManager.getLogger(); private final Actor actor; private final Channel channel; private Flow.Subscription subscription; public ActorSubscriber(@NotNull Actor actor, @NotNull Channel channel) { this.actor = actor; this.channel = channel; } @Override public void onSubscribe(@NotNull Flow.Subscription subscription) { logger.atInfo().log("actor {} is subscribed to channel {}", actor.name(), channel.name()); this.subscription = subscription; subscription.request(1); } @Override public void onNext(@NotNull T message) { logger.atInfo().log("actor {} received message {} from channel {}", actor.name(), message, channel.name()); actor.receive(message); subscription.request(1); } @Override public void onError(Throwable e) { logger.atError().withThrowable(e).log("actor {} has error on channel {}", actor.name(), channel.name()); } @Override public void onComplete() { logger.atInfo().log("actor {} has completed on channel {}", actor.name(), channel.name()); } } public Channel(@NotNull String name) { this.name = name; publisher = new SubmissionPublisher<>(); } public String name() { return name; } public SubmissionPublisher publisher() { return publisher; } /** * Subscribe an actor to the channel. The actor will receive messages from the channel. * @param actor actor to subscribe */ public void subscribe(@NotNull Actor actor) { publisher.subscribe(new ActorSubscriber<>(actor, this)); } /** * Dispatch a message to all subscribers of the channel. * @param message message to dispatch */ public void publish(@NotNull T message) { publisher.submit(message); } @Override public void close() { publisher.close(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy