io.hekate.messaging.internal.BroadcastContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hekate-all Show documentation
Show all versions of hekate-all Show documentation
Java library for cluster communications and computing.
/*
* Copyright 2020 The Hekate Project
*
* The Hekate Project licenses this file to you 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:
*
* http://www.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 io.hekate.messaging.internal;
import io.hekate.cluster.ClusterNode;
import io.hekate.messaging.MessageTimeoutException;
import io.hekate.messaging.operation.BroadcastFuture;
import io.hekate.messaging.operation.BroadcastResult;
import io.hekate.util.format.ToString;
import io.hekate.util.format.ToStringIgnore;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static java.util.Collections.emptyMap;
class BroadcastContext implements BroadcastResult {
private final T message;
private final List nodes;
@ToStringIgnore
private final BroadcastFuture future;
private Map errors;
@ToStringIgnore
private int remaining;
public BroadcastContext(T message, List nodes, BroadcastFuture future) {
this.message = message;
this.nodes = new ArrayList<>(nodes); // Copy since node list can be modified.
this.remaining = nodes.size();
this.future = future;
}
@Override
public T message() {
return message;
}
@Override
public List nodes() {
synchronized (this) {
return nodes;
}
}
@Override
public Map errors() {
synchronized (this) {
return errors == null ? emptyMap() : errors;
}
}
public boolean forgetNode(ClusterNode node) {
synchronized (this) {
if (nodes.remove(node)) {
remaining--;
}
return remaining == 0;
}
}
public BroadcastFuture future() {
return future;
}
boolean onSendSuccess() {
synchronized (this) {
remaining--;
return remaining == 0;
}
}
boolean onSendFailure(ClusterNode node, Throwable error) {
synchronized (this) {
if (errors == null) {
errors = new HashMap<>(remaining, 1.0f);
}
errors.put(node, error);
remaining--;
return remaining == 0;
}
}
void complete() {
future.complete(this);
}
boolean isTimedOut() {
return errors().values().stream().anyMatch(e -> e instanceof MessageTimeoutException);
}
@Override
public String toString() {
return ToString.format(BroadcastResult.class, this);
}
}