All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.vlingo.xoom.cluster.model.attribute.AttributesAgentActor Maven / Gradle / Ivy
// Copyright © 2012-2022 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.xoom.cluster.model.attribute;
import io.vlingo.xoom.actors.Actor;
import io.vlingo.xoom.actors.Logger;
import io.vlingo.xoom.cluster.model.Properties;
import io.vlingo.xoom.cluster.model.application.ClusterApplication;
import io.vlingo.xoom.cluster.model.attribute.message.ApplicationMessageType;
import io.vlingo.xoom.cluster.model.attribute.message.ReceivedAttributeMessage;
import io.vlingo.xoom.cluster.model.node.Registry;
import io.vlingo.xoom.cluster.model.outbound.OperationalOutboundStream;
import io.vlingo.xoom.common.Scheduled;
import io.vlingo.xoom.wire.message.RawMessage;
import io.vlingo.xoom.wire.node.AddressType;
import io.vlingo.xoom.wire.node.Node;
public class AttributesAgentActor extends Actor implements AttributesAgent {
private final AttributesClient client;
private final ConfirmationInterest confirmationInterest;
private final ConfirmingDistributor confirmingDistributor;
private final Node node;
private final RemoteAttributeRequestHandler remoteRequestHandler;
private final Registry registry;
private final AttributeSetRepository repository;
public AttributesAgentActor(
final Node node,
final ClusterApplication application,
final OperationalOutboundStream outbound,
final Registry registry,
final Logger logger) {
this(node, application, outbound, new NoOpConfirmationInterest(logger), registry, logger);
}
@SuppressWarnings("unchecked")
public AttributesAgentActor(
final Node node,
final ClusterApplication application,
final OperationalOutboundStream outbound,
final ConfirmationInterest confirmationInterest,
final Registry registry,
final Logger logger) {
this.node = node;
this.confirmationInterest = confirmationInterest;
this.client = AttributesClient.with(selfAs(AttributesAgent.class));
this.confirmingDistributor = new ConfirmingDistributor(application, node, outbound, registry::allOtherNodes, logger);
this.repository = new AttributeSetRepository();
this.remoteRequestHandler = new RemoteAttributeRequestHandler(confirmingDistributor, repository, registry::getNode, logger);
this.registry = registry;
application.informAttributesClient(this.client);
stage().scheduler()
.schedule(selfAs(Scheduled.class), null, 1000L, Properties.instance().clusterAttributesRedistributionInterval());
}
//=========================================
// AttributesAgent (core)
//=========================================
@Override
public void add(final String attributeSetName, final String attributeName, final T value) {
final AttributeSet set = repository.attributeSetOf(attributeSetName);
if (set.isNone()) {
final AttributeSet newSet = AttributeSet.named(attributeSetName);
newSet.addIfAbsent(Attribute.from(attributeName, value));
repository.add(newSet);
client.syncWith(newSet);
confirmingDistributor.distributeCreate(newSet);
} else {
final TrackedAttribute newlyTracked = set.addIfAbsent(Attribute.from(attributeName, value));
if (!newlyTracked.isDistributed()) {
confirmingDistributor.distribute(set, newlyTracked, ApplicationMessageType.AddAttribute);
}
}
}
@Override
public void replace(final String attributeSetName, final String attributeName, final T value) {
final AttributeSet set = repository.attributeSetOf(attributeSetName);
if (!set.isNone()) {
final TrackedAttribute tracked = set.attributeNamed(attributeName);
if (tracked.isPresent()) {
final Attribute other = Attribute.from(attributeName, value);
if (!tracked.sameAs(other)) {
final TrackedAttribute newlyTracked = set.replace(tracked.replacingValueWith(other));
if (newlyTracked.isPresent()) {
client.syncWith(set);
confirmingDistributor.distribute(set, newlyTracked, ApplicationMessageType.ReplaceAttribute);
}
}
}
}
}
@Override
public void remove(final String attributeSetName, final String attributeName) {
final AttributeSet set = repository.attributeSetOf(attributeSetName);
if (!set.isNone()) {
final TrackedAttribute tracked = set.attributeNamed(attributeName);
if (tracked.isPresent()) {
final TrackedAttribute untracked = set.remove(tracked.attribute);
if (untracked.isPresent()) {
client.syncWith(set);
confirmingDistributor.distribute(set, untracked, ApplicationMessageType.RemoveAttribute);
}
}
}
}
@Override
public void removeAll(final String attributeSetName) {
final AttributeSet set = repository.attributeSetOf(attributeSetName);
if (!set.isNone()) {
repository.remove(attributeSetName);
client.syncWithout(set);
confirmingDistributor.distributeRemove(set);
}
}
//=========================================
// NodeSynchronizer
//=========================================
@Override
public void synchronize(final Node nodeToSynchronize) {
if (!node.equals(nodeToSynchronize)) {
confirmingDistributor.synchronizeTo(repository.all(), nodeToSynchronize);
}
}
//=========================================
// InboundStreamInterest (operations App)
//=========================================
@Override
public void handleInboundStreamMessage(final AddressType addressType, final RawMessage message) {
if (addressType.isOperational()) {
final ReceivedAttributeMessage request = new ReceivedAttributeMessage(message);
final ApplicationMessageType type = request.type();
switch (type) {
case CreateAttributeSet:
remoteRequestHandler.createAttributeSet(request);
break;
case AddAttribute:
remoteRequestHandler.addAttribute(request);
break;
case ReplaceAttribute:
remoteRequestHandler.replaceAttribute(request);
break;
case RemoveAttribute:
remoteRequestHandler.removeAttribute(request);
break;
case RemoveAttributeSet:
remoteRequestHandler.removeAttributeSet(request);
break;
case ConfirmCreateAttributeSet:
case ConfirmAddAttribute:
case ConfirmReplaceAttribute:
case ConfirmRemoveAttribute:
case ConfirmRemoveAttributeSet:
final Node sourceNode = registry.getNode(request.sourceNodeId());
if (sourceNode == null) {
logger().warn("Failed to perform " + type.name() + " because source node " + request.sourceNodeId() + " is not part of the cluster anymore!");
} else {
confirmingDistributor.acknowledgeConfirmation(request.correlatingMessageId(), sourceNode);
confirmationInterest.confirm(request.sourceNodeId(), request.attributeSetName(), request.attributeName(), type);
}
break;
default:
logger().warn("Received unknown message: " + type.name());
break;
}
}
}
//=========================================
// Scheduled
//=========================================
@Override
public void intervalSignal(final Scheduled scheduled, final Object data) {
confirmingDistributor.redistributeUnconfirmed();
}
//=========================================
// Stoppable
//=========================================
@Override
public void stop() {
if (isStopped()) {
return;
}
repository.removeAll();
super.stop();
}
}