// Copyright © 2012-2020 VLINGO LABS. 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.lattice.model.projection; import java.util.Arrays; import java.util.Collection; import java.util.List; import io.vlingo.actors.Definition; import io.vlingo.actors.Protocols; import io.vlingo.symbio.Entry; import io.vlingo.symbio.State; import io.vlingo.symbio.store.Result; import io.vlingo.symbio.store.dispatch.ConfirmDispatchedResultInterest; import io.vlingo.symbio.store.dispatch.Dispatchable; import io.vlingo.symbio.store.dispatch.Dispatcher; import io.vlingo.symbio.store.dispatch.DispatcherControl; public abstract class ProjectionDispatcherActor<E extends Entry<?>, RS extends State<?>> extends AbstractProjectionDispatcherActor implements Dispatcher<Dispatchable<E, RS>>, ProjectionDispatcher, ConfirmDispatchedResultInterest { private ConfirmDispatchedResultInterest interest; private DispatcherControl control; private final MultiConfirming multiConfirming; private final ProjectionControl multiConfirmingProjectionControl; private final ProjectionControl projectionControl; protected ProjectionDispatcherActor() { this(Arrays.asList(), MultiConfirming.DefaultExpirationLimit); } protected ProjectionDispatcherActor(final Collection<ProjectToDescription> projectToDescriptions, final long multiConfirmationsExpiration) { super(projectToDescriptions); this.interest = selfAs(ConfirmDispatchedResultInterest.class); this.projectionControl = new ProjectionControl() { @Override public void confirmProjected(String projectionId) { if (control != null) { control.confirmDispatched(projectionId, interest); } else if (requiresDispatchedConfirmation()) { logger().error("WARNING: ProjectionDispatcher control is not set; unconfirmed: " + projectionId); } } }; final Protocols protocols = childActorFor( new Class[] { MultiConfirming.class, ProjectionControl.class }, Definition.has(MultiConfirmingProjectionControlActor.class, Definition.parameters(projectionControl, multiConfirmationsExpiration))); this.multiConfirming = protocols.get(0); this.multiConfirmingProjectionControl = protocols.get(1); } //===================================== // Dispatcher //===================================== @Override public void controlWith(final DispatcherControl control) { this.control = control; } //===================================== // ConfirmDispatchedResultInterest //===================================== @Override public void confirmDispatchedResultedIn(final Result result, final String dispatchId) { } //===================================== // internal implementation //===================================== protected abstract boolean requiresDispatchedConfirmation(); protected void dispatch(final String dispatchId, final Projectable projectable) { final List<Projection> projections = projectionsFor(projectable.becauseOf()); final int count = projections.size(); if (count > 1) { multiConfirming.manageConfirmationsFor(projectable, count); } for (final Projection projection : projections) { projection.projectWith(projectable, count > 1 ? multiConfirmingProjectionControl : projectionControl); } } }