org.jgroups.util.ResponseCollector Maven / Gradle / Ivy
Go to download
This artifact provides a single jar that contains all classes required to use remote Jakarta Enterprise Beans and Jakarta Messaging, including
all dependencies. It is intended for use by those not using maven, maven users should just import the Jakarta Enterprise Beans and
Jakarta Messaging BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up
with different versions on classes on the class path).
package org.jgroups.util;
import org.jgroups.Address;
import org.jgroups.annotations.GuardedBy;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/** Similar to AckCollector, but collects responses from cluster members, not just acks. Null is not a valid key.
* @author Bela Ban
*/
public class ResponseCollector implements org.jgroups.util.Condition {
@GuardedBy("lock")
private final Map responses;
private final Lock lock=new ReentrantLock(false);
private final CondVar cond=new CondVar(lock);
/**
*
* @param members List of members from which we expect responses
*/
public ResponseCollector(Collection members) {
responses=members != null? new HashMap(members.size()) : new HashMap();
reset(members);
}
public ResponseCollector(Address ... members) {
responses=members != null? new HashMap(members.length) : new HashMap();
reset(members);
}
public ResponseCollector() {
responses=new HashMap<>();
}
public void add(Address member, T data) {
if(member == null)
return;
lock.lock();
try {
if(responses.containsKey(member)) {
responses.put(member, data);
cond.signal(true);
}
}
finally {
lock.unlock();
}
}
public void remove(Address member) {
if(member == null)
return;
lock.lock();
try {
if(responses.remove(member) != null)
cond.signal(true);
}
finally {
lock.unlock();
}
}
public void remove(List members) {
if(members == null || members.isEmpty())
return;
lock.lock();
try {
for(Address member: members)
responses.remove(member);
cond.signal(true);
}
finally {
lock.unlock();
}
}
public void retainAll(List members) {
if(members == null || members.isEmpty())
return;
lock.lock();
try {
if(responses.keySet().retainAll(members))
cond.signal(true);
}
finally {
lock.unlock();
}
}
public void suspect(Address member) {
remove(member);
}
public boolean isMet() {
return hasAllResponses();
}
public boolean hasAllResponses() {
lock.lock();
try {
if(responses.isEmpty())
return true;
for(Map.Entry entry: responses.entrySet()) {
if(entry.getValue() == null)
return false;
}
return true;
}
finally {
lock.unlock();
}
}
public int numberOfValidResponses() {
int retval=0;
lock.lock();
try {
for(Map.Entry entry: responses.entrySet()) {
if(entry.getValue() != null)
retval++;
}
return retval;
}
finally {
lock.unlock();
}
}
/** Returns a list of members which didn't send a valid response */
public List getMissing() {
List retval=new ArrayList<>();
for(Map.Entry entry: responses.entrySet()) {
if(entry.getValue() == null)
retval.add(entry.getKey());
}
return retval;
}
public List getValidResults() {
List retval=new ArrayList<>();
for(Map.Entry entry: responses.entrySet()) {
if(entry.getValue() != null)
retval.add(entry.getKey());
}
return retval;
}
public Map getResults() {
return responses;
}
public int size() {
lock.lock();
try {
return responses.size();
}
finally {
lock.unlock();
}
}
/**
* Waits until all responses have been received, or until a timeout has elapsed.
* @param timeout Number of milliseconds to wait max. This value needs to be greater than 0, or else
* it will be adjusted to 2000
* @return boolean True if all responses have been received within timeout ms, else false (e.g. if interrupted)
*/
public boolean waitForAllResponses(long timeout) {
if(timeout <= 0)
timeout=2000L;
return cond.waitFor(this, timeout, TimeUnit.MILLISECONDS);
}
public void reset() {
reset((Collection)null);
}
public void reset(Collection members) {
lock.lock();
try {
responses.clear();
if(members != null) {
for(Address mbr: members)
responses.put(mbr, null);
}
cond.signal(true);
}
finally {
lock.unlock();
}
}
public void reset(Address ... members) {
lock.lock();
try {
responses.clear();
if(members != null) {
for(Address mbr: members)
responses.put(mbr, null);
}
cond.signal(true);
}
finally {
lock.unlock();
}
}
public String toString() {
StringBuilder sb=new StringBuilder();
sb.append(responses).append(", complete=").append(hasAllResponses());
return sb.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy