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

io.vlingo.actors.Router Maven / Gradle / Ivy

Go to download

Type safe Actor Model toolkit for reactive concurrency and resiliency using Java and other JVM languages.

There is a newer version: 1.7.5
Show newest version
// Copyright © 2012-2018 Vaughn Vernon. All rights reserved.
//
// This Source Code Form is subject to the terms of the
// Mozilla Public License, v. 2.0. If a copy of the MPL
// was not distributed with this file, You can obtain
// one at https://mozilla.org/MPL/2.0/.
package io.vlingo.actors;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;

import io.vlingo.common.Completes;
import io.vlingo.common.PentaConsumer;
import io.vlingo.common.PentaFunction;
import io.vlingo.common.QuadConsumer;
import io.vlingo.common.QuadFunction;
import io.vlingo.common.TriConsumer;
import io.vlingo.common.TriFunction;
/**
 * Router is a kind of {@link Actor} that forwards a message
 * to one or more other {@link Actor actors} according to a
 * computed {@link Routing}.
 */
public abstract class Router

extends Actor { protected final List> routees; public Router(final RouterSpecification

specification) { this.routees = new ArrayList>(); initRoutees(specification); } protected void initRoutees(final RouterSpecification

specification) { for (int i = 0; i < specification.initialPoolSize(); i++) { P child = childActorFor(specification.routerProtocol(), specification.routerDefinition()); subscribe(Routee.of(child)); } } protected List> routees() { return Collections.unmodifiableList(routees); } public Routee

routeeAt(int index) { return (index < 0 || index >= routees.size()) ? null : routees.get(index); } //SUBSCRIPTION protected void subscribe(Routee

routee) { if (!routees.contains(routee)) routees.add(routee); } protected void subscribe(List> toSubscribe) { toSubscribe.forEach(routee -> subscribe(routee)); } protected void unsubscribe(Routee

routee) { routees.remove(routee); } protected void unsubscribe(List> toUnsubscribe) { toUnsubscribe.forEach(routee -> unsubscribe(routee)); } //ROUTE COMPUTATION protected abstract Routing

computeRouting(); protected Routing

routingFor(final T1 routable1) { /* by default, assume the routing is not dependent on message content */ return computeRouting(); } protected Routing

routingFor(final T1 routable1, final T2 routable2) { /* by default, assume the routing is not dependent on message content */ return computeRouting(); } protected Routing

routingFor(final T1 routable1, final T2 routable2, final T3 routable3) { /* by default, assume the routing is not dependent on message content */ return computeRouting(); } protected Routing

routingFor(final T1 routable1, final T2 routable2, final T3 routable3, final T4 routable4) { /* by default, assume the routing is not dependent on message content */ return computeRouting(); } //DISPATCHING - COMMANDS protected void dispatchCommand(final BiConsumer action, final T1 routable1) { routingFor(routable1) .routees() .forEach(routee -> routee.receiveCommand(action, routable1)); } protected void dispatchCommand(final TriConsumer action, final T1 routable1, final T2 routable2) { routingFor(routable1, routable2) .routees() .forEach(routee -> routee.receiveCommand(action, routable1, routable2)); } protected void dispatchCommand(final QuadConsumer action, final T1 routable1, final T2 routable2, final T3 routable3) { routingFor(routable1, routable2, routable3) .routees() .forEach(routee -> routee.receiveCommand(action, routable1, routable2, routable3)); } protected void dispatchCommand(final PentaConsumer action, final T1 routable1, final T2 routable2, final T3 routable3, final T4 routable4) { routingFor(routable1, routable2, routable3, routable4) .routees() .forEach(routee -> routee.receiveCommand(action, routable1, routable2, routable3, routable4)); } //DISPATCHING - QUERIES @SuppressWarnings("unchecked") protected > R dispatchQuery(final BiFunction query, final T1 routable1) { final CompletesEventually completesEventually = completesEventually(); routingFor(routable1) .first() //by default, for protocols with a return value, route only to first routee .receiveQuery(query, routable1) .andThenConsume(outcome -> completesEventually.with(outcome)); return (R) completes(); //this is a fake out; the real completes doesn't happen until inside the lambda } @SuppressWarnings("unchecked") protected > R dispatchQuery(final TriFunction query, final T1 routable1, final T2 routable2) { final CompletesEventually completesEventually = completesEventually(); routingFor(routable1, routable2) .first() //by default, for protocols with a return value, route only to first routee .receiveQuery(query, routable1, routable2) .andThenConsume(outcome -> completesEventually.with(outcome)); return (R) completes(); //this is a fake out; the real completes doesn't happen until inside the lambda } @SuppressWarnings("unchecked") protected > R dispatchQuery(final QuadFunction query, final T1 routable1, final T2 routable2, final T3 routable3) { final CompletesEventually completesEventually = completesEventually(); routingFor(routable1, routable2) .first() //by default, for protocols with a return value, route only to first routee .receiveQuery(query, routable1, routable2, routable3) .andThenConsume(outcome -> completesEventually.with(outcome)); return (R) completes(); //this is a fake out; the real completes doesn't happen until inside the lambda } @SuppressWarnings("unchecked") protected > R dispatchQuery(final PentaFunction query, final T1 routable1, final T2 routable2, final T3 routable3, final T4 routable4) { final CompletesEventually completesEventually = completesEventually(); routingFor(routable1, routable2) .first() //by default, for protocols with a return value, route only to first routee .receiveQuery(query, routable1, routable2, routable3, routable4) .andThenConsume(outcome -> completesEventually.with(outcome)); return (R) completes(); //this is a fake out; the real completes doesn't happen until inside the lambda } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy