com.tangosol.net.topic.Publisher Maven / Gradle / Ivy
Show all versions of coherence Show documentation
/*
* Copyright (c) 2000, 2021, 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.net.topic;
import com.oracle.coherence.common.util.Options;
import com.tangosol.io.ExternalizableLite;
import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;
import com.tangosol.net.FlowControl;
import com.tangosol.util.Base;
import com.tangosol.util.ExternalizableHelper;
import com.tangosol.util.function.Remote;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.ToIntFunction;
/**
* Publisher provides a means to publish values to the {@link NamedTopic}.
*
* The factory method {@link NamedTopic#createPublisher(Publisher.Option[])} or
* {@link com.tangosol.net.Session#createPublisher(String)} allows one to specify one or more
* {@link Publisher.Option}s to configure the {@link Publisher}.
*
* Since the {@link #publish(Object)} method is asynchronous, there is a {@link #flush()} that allows one to
* block until all outstanding {@link #publish sent values} for the {@link Publisher} have completed.
*
*
Channels
* Topics use the concept of channels to improve scalability. This is similar to how Coherence uses partition for caches
* but to avoid confusion the name channel was chosen. The default is the next prime above the square root of the
* partition count for the underlying cache service, which for the default partition count of 257 is 17 channels.
*
* {@link Publisher Publishers} publish messages to a channel based on their ordering configuration. Subscribers then
* subscribe from channels by assigning channel ownership to subscribers. An anonymous subscriber has ownership of all
* channels. A subscriber that is part of a subscriber group has ownership of a sub-set of the available channels.
*
* Channel count is configurable, but ideally should not be set too high nor too low. For example setting the channel
* count to 1, would mean that all publishers contend to publish to a single channel, and that only one subscriber
* in a subscriber group will be able to receive messages. Setting the channel count too high (above say the number of
* publishers) may mean that some channels never receive any messages and are wasted. Finding the appropriate value is
* admittedly non-trivial, however when faced with maxing out throughput from a publishers perspective this is a
* configuration that can be tweaked.
*
*
Positions
* Elements in a {@link NamedTopic} are published to a channel have a unique {@link Position} within that channel.
* A {@link Position} is an opaque representation of the underlying position as theoretically the implementation of
* the {@link Position} could change for different types of topic. Positions are used in various places in the API,
* for example, positions can be committed, and they can be used to move the subscriber to backwards or forwards
* within channels. A {@link Position} is serializable so they can be stored and recovered to later reset a subscriber
* to a desired position. Positions are {@link Comparable} so positions for elements can be used to determine whether
* how two elements related to each other within a channel.
*
* @param the value type
*
* @author jf/jk/mf 2015.06.03
* @since Coherence 14.1.1
*/
public interface Publisher
extends AutoCloseable
{
/**
* Asynchronously publish the specified value to the topic.
*
* {@link CompletableFuture#cancel(boolean) Cancellation} of the returned future is best
* effort and is not guaranteed to stop the corresponding publication of the value, for example
* example the request may already be on the wire and being processed on a storage member.
*
* @param value the value to add to the topic
*
* @return a {@link CompletableFuture} which can be used to identify when the value has been
* delivered to the topic
*
* @deprecated Use {@link Publisher#publish(Object)} which returns metadata about the published value
*
* @throws IllegalStateException if this Publisher is closed or the parent topic
* has been released or destroyed
*/
@Deprecated
public default CompletableFuture send(V value)
{
return publish(value).thenAccept(_void -> {});
}
/**
* Asynchronously publish the specified value to the topic.
*
* {@link CompletableFuture#cancel(boolean) Cancellation} of the returned future is best
* effort and is not guaranteed to stop the corresponding publication of the value, for example
* example the request may already be on the wire and being processed on a storage member.
*
* Published messages will be recieved by subscribers in order determined by the {@link OrderBy} option used to
* create this {@link Publisher}.
* Message ordering can also be controlled by publishing values that implement the {@link Orderable} interface,
* in which case the order identifier provided by the {@link Orderable} value will override any ordering
* configured for the {@link Publisher}.
*
* @param value the value to add to the topic
*
* @return a {@link CompletableFuture} containing the {@link Status}, which can be
* used to identify when the value has been delivered to the topic and the position
* it was added to the topic
*
* @throws IllegalStateException if this Publisher is closed or the parent topic has been released
* or destroyed
*/
public CompletableFuture publish(V value);
/**
* Return the {@link FlowControl} object governing this publisher.
*
* @return the FlowControl object.
*/
public FlowControl getFlowControl();
/**
* Obtain a {@link CompletableFuture} that will be complete when
* all of the currently outstanding publish operations complete.
*
* The returned {@link CompletableFuture} will always complete
* normally, even if the outstanding operations complete exceptionally.
*
* @return a {@link CompletableFuture} that will be completed when
* all of the currently outstanding publish operations are complete
*/
public CompletableFuture flush();
/**
* Close this {@link Publisher}.
*
* This is a blocking method and will wait until all outstanding
* {@link CompletableFuture}s returned from previous calls
* to {@link #publish(Object)} have completed before returning.
*/
@Override
public void close();
/**
* Add an action to be executed when this {@link Publisher} is closed.
*
* @param action the action to execute
*/
public void onClose(Runnable action);
/**
* Returns the number of channels in the underlying {@link NamedTopic} that can be published to.
*
* @return the number of channels in the underlying {@link NamedTopic} that can be published to
*/
public int getChannelCount();
/**
* Returns the underlying {@link NamedTopic} that this {@link Publisher} publishes to.
*
* @return the underlying {@link NamedTopic} that this {@link Publisher} publishes to
*/
public NamedTopic getNamedTopic();
/**
* Specifies whether or not the {@link Publisher} is active.
*
* @return true if the NamedCache is active; false otherwise
*/
public boolean isActive();
// ----- inner interface: ElementMetadata -------------------------------
/**
* The status for a successfully published element.
*/
public interface Status
{
/**
* Returns the channel that the element was published to.
*
* @return the channel that the element was published to
*/
public int getChannel();
/**
* Returns the {@link Position} in the channel that the element was published to.
*
* @return the {@link Position} in the channel that the element was published to
*/
public Position getPosition();
}
// ----- inner interface: Option ----------------------------------------
/**
* A marker interface to indicate that a class is a valid {@link Option}
* for a {@link Publisher}.
*
*
* Options to use with {@link NamedTopic#createPublisher(Publisher.Option...)}
*
* Publisher Option
* Description
*
*
* {@link OnFailure#Stop}
* Default. If an individual {@link #publish} invocation fails then stop any further publishing and close the {@link Publisher}.
*
*
* {@link OnFailure#Continue}
* If an individual {@link #publish} invocation fails then skip that value and continue to publish other values.
*
*
* {@link FailOnFull FailOnFull.enabled()}
* When the storage size of the unprocessed values on the topic exceed a configured high-units,
* the {@link CompletableFuture} returned from the {@link #publish} invocation should complete exceptionally.
*
Overrides the default to block completing until the operation completes when space becomes available.
*
*
* {@link OrderBy#thread()}
* Default. Ensure that all {@link #publish values sent} from
* the same thread are stored sequentially.
*
*
* {@link OrderBy#none()}
* Enforce no specific ordering between {@link #publish sent values} allowing
* for the greatest level of parallelism
*
*
* {@link OrderBy#id(int)}
* Ensure ordering of {@link #publish sent values} across
* all threads which share the same id.
*
*
* {@link OrderBy#value(ToIntFunction)}
* Compute the unit-of-order based on the applying this method on {@link #publish sent value}
*
*
* {@link OrderBy#value(Remote.ToIntFunction)}
* Compute the unit-of-order based on the applying this method on {@link #publish sent value}
*
*
*/
public interface Option
{
}
// ----- inner class: OnFailure -----------------------------------------
/**
* This option controls how a {@link Publisher} handles a failure of an individual
* {@link #publish} call.
*/
public enum OnFailure
implements Option