com.tangosol.util.aggregator.AsynchronousAggregator Maven / Gradle / Ivy
Show all versions of coherence Show documentation
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
package com.tangosol.util.aggregator;
import com.tangosol.net.NamedCache;
import com.tangosol.util.InvocableMap;
import com.tangosol.util.InvocableMap.EntryAggregator;
import com.tangosol.util.InvocableMap.StreamingAggregator;
import com.tangosol.util.processor.AsynchronousProcessor;
import java.util.concurrent.Future;
/**
* A marker {@link EntryAggregator EntryAggregator} wrapper class that allows for
* an asynchronous invocation of the underlying aggregator. When used as a
* {@link Future} (without extending), this implementation will simply provide
* {@link Future#get the result} of asynchronous streaming aggregation according
* to semantics of the corresponding {@link EntryAggregator#aggregate
* EntryAggregator.aggregate} contract.
*
* More advanced use would require extending this class and overriding {@link
* #onResult} and {@link #onException} methods. It's very important that
* overriding implementations of these methods must be non-blocking. For example,
* any use of {@link NamedCache} API is completely disallowed with the only
* exception of {@link AsynchronousAggregator#AsynchronousAggregator(InvocableMap.StreamingAggregator) AsynchronousAggregators} and
* {@link AsynchronousProcessor#AsynchronousProcessor(InvocableMap.EntryProcessor)}
*
* The underlying entry processor is guaranteed to have been fully executed when
* either {@link #onResult onResult()} or {@link #onException onException()} are called.
*
* Note 1: Neither this class nor its extensions need to be serializable. Only the
* underlying aggregator is serialized and sent to corresponding servers for
* execution.
*
* Note 2: This feature is not available on Coherence*Extend clients.
*
* @param the type of the Map entry keys
* @param the type of the Map entry values
* @param the type of the intermediate result during the parallel stage
* @param the type of the value returned by the StreamingAggregator
*
* @see AsynchronousProcessor
* @author gg/mf 2012.12.21
*/
public class AsynchronousAggregator
extends AbstractAsynchronousAggregator
implements EntryAggregator
{
/**
* Construct an AsynchronousAggregator for a given streaming aggregator.
*
* @param aggregator the underlying streaming aggregator
*/
public AsynchronousAggregator(StreamingAggregator aggregator)
{
this(aggregator, Thread.currentThread().hashCode());
}
/**
* Construct an AsynchronousAggregator for a given streaming aggregator.
*
* @param aggregator the underlying streaming aggregator
* @param iUnitOrderId the unit-of-order id for this aggregator
*/
public AsynchronousAggregator(StreamingAggregator aggregator,
int iUnitOrderId)
{
super(aggregator, iUnitOrderId);
}
// ----- AsynchronousAggregator API -------------------------------------
/**
* Called when the aggregation result is available.
*
* For ordering guarantees see {@link #getUnitOfOrderId}.
*
* Note: Overriding implementations of this method must be non-blocking.
*
* @param result the result
*/
public void onResult(P result)
{
if (!isDone())
{
if (!m_aggregator.combine(result))
{
// short-circuit - we are done
onComplete();
}
}
}
/**
* Called if the operation failed for any reason.
*
* Note: Overriding implementations of this method must be non-blocking.
*
* @param eReason the reason of failure
*/
public void onException(Throwable eReason)
{
m_eReason = eReason;
}
@Override
public void onComplete()
{
Throwable eReason = m_eReason;
if (eReason == null)
{
complete(m_aggregator::finalizeResult);
}
else
{
completeExceptionally(eReason);
}
}
// ----- data fields -----------------------------------------------------
/**
* Reason for the failed operation.
*/
protected volatile Throwable m_eReason;
}