All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tangosol.net.topic.NamedTopic Maven / Gradle / Ivy

There is a newer version: 24.09
Show newest version
/*
 * Copyright (c) 2000, 2023, Oracle and/or its affiliates.
 *
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * https://oss.oracle.com/licenses/upl.
 */
package com.tangosol.net.topic;


import com.tangosol.coherence.config.unit.Seconds;
import com.tangosol.net.NamedCollection;

import com.tangosol.net.TopicService;
import com.tangosol.util.Binary;
import com.tangosol.util.ClassHelper;
import com.tangosol.util.Filter;
import com.tangosol.util.ValueExtractor;

import java.util.Set;

/**
 * NamedTopic represents a topic entity for publish/subscribe messaging.
 * 

* A topic may have any number of {@link Publisher publishers} or {@link Subscriber subscribers}. * {@link Subscriber}s subscribe directly to the topic or subscribe to a logical {@link Subscriber.Name subscriber group} of the topic. * Each published value to a topic is delivered to all direct topic {@link Subscriber}s and * each subscriber group of the topic. Each value of a subscriber group is only consumed by one {@link Subscriber subscriber group member}. * Thus, each subscriber group in effect behaves like a queue over the topic data. *

* Once {@link Publisher#publish published}, a value will be retained by the topic until it has either * expired or has been {@link Subscriber#receive received} by all {@link Subscriber.Name subscriber group(s)} * and direct topic {@link Subscriber}(s) which were registered prior to it being published. * The ordering of values within the topic is dependent on the {@link Publisher.OrderBy} option. *

* Subscriber Group Lifecycle
* A subscriber group is created either at configuration time or dynamically. * A subscriber-group child element of a topic-mapping element in a cache configuration file statically * configures a subscriber group when the topic is created, ensuring all values published to the * topic are also delivered to the statically configured subscriber group. * A subscriber group is created dynamically when a {@link NamedTopic#createSubscriber(Subscriber.Option[]) createSubscriber call} specifies a * subscriber group name using the option {@link Subscriber.Name#of(String)} and the subscriber group does not exist on the {@link NamedTopic}. *

* One must actively manage a {@link NamedTopic#getSubscriberGroups() NamedTopic's logical subscriber groups} since their life span * is independent of their active {@link Subscriber} membership. * {@link NamedTopic#destroySubscriberGroup(String)} releases storage and stops accumulating topic values for a subscriber group. *

* To release storage resources for unconsumed values for a direct topic {@link Subscriber}, it is sufficient to ensure it is {@link Subscriber#close() closed}. * Both topic {@link Publisher} and {@link Subscriber} can be defined with the try-with-resource pattern to ensure their resources are * closed when no longer in scope. * * @param the type of the topic values * * @author jf/jk/mf 2015.06.03 * @since Coherence 14.1.1 * * @see Publisher * @see Subscriber */ @SuppressWarnings("unchecked") public interface NamedTopic extends NamedCollection { // ----- NamedTopic interface ------------------------------------------- /** * Create a {@link Publisher} that can publish values into this {@link NamedTopic}. * * @param options the {@link Publisher.Option}s controlling the {@link Publisher} * * @return a {@link Publisher} that can publish values into this {@link NamedTopic} */ Publisher createPublisher(Publisher.Option... options); /** * Create a {@link Publisher} that can publish values into this {@link NamedTopic}. * * @return a {@link Publisher} that can publish values into this {@link NamedTopic} */ default Publisher createPublisher() { // this method variant only exists so that callers which don't specify options won't get // a compile-time warning about the implicit generic array creation return createPublisher(new Publisher.Option[0]); } /** * Create a {@link Subscriber} that can receive values from this {@link NamedTopic}. * * @param options the {@link Subscriber.Option}s controlling the {@link Subscriber} * * @return a {@link Subscriber} that can receive values from this {@link NamedTopic} */ Subscriber createSubscriber(Subscriber.Option... options); /** * Create a direct {@link Subscriber} to the topic that receives all values from this {@link NamedTopic}. * * @return a {@link Subscriber} that can receive values from this {@link NamedTopic} */ default Subscriber createSubscriber() { // this method variant only exists so that callers which don't specify options won't get // a compile-time warning about the implicit generic array creation return createSubscriber(new Subscriber.Option[0]); } /** * Ensure that the specified subscriber group exists for this topic. * * @param sName the name of the subscriber group * * @throws IllegalStateException if the subscriber group already exists with a different filter * or converter function */ default void ensureSubscriberGroup(String sName) { ensureSubscriberGroup(sName, null, null); } /** * Ensure that the specified subscriber group exists for this topic. * * @param sGroup the name of the subscriber group * @param filter the {@link Filter} used to filter messages to be received by subscribers in the group * @param extractor the {@link ValueExtractor} used to convert messages to be received by subscribers in the group * * @throws IllegalStateException if the subscriber group already exists with a different filter * or converter extractor */ void ensureSubscriberGroup(String sGroup, Filter filter, ValueExtractor extractor); /** * Destroy the {@link Subscriber.Name named} subscriber group for the associated topic. *

* Releases storage and stops accumulating topic values for destroyed subscriber group. * This operation will impact all {@link Subscriber members} of the subscriber group. */ void destroySubscriberGroup(String sGroup); /** * Return the set of {@link Subscriber.Name named} subscriber group(s) and statically configured subscriber-group(s). * * @return the set of named subscriber groups. */ Set getSubscriberGroups(); /** * Specifies whether this NamedTopic has been destroyed. *

* Implementations must override this method to provide the necessary information. * * @return true if the NamedTopic has been destroyed; false otherwise */ default boolean isDestroyed() { // to avoid cumbersome caller exception handling; // default is a no-op. return false; } /** * Specifies whether this NamedTopic has been released. *

* Implementations must override this method to provide the necessary information. * * @return true if the NamedTopic has been released; false otherwise */ default boolean isReleased() { // to avoid cumbersome caller exception handling; // default is a no-op. return false; } /** * Returns the number of channels that this topic has. * * @return the number of channels that this topic has */ int getChannelCount(); /** * Returns the number of remaining messages to be read from the topic for the specific subscriber group. *

* This method is a sum of the remaining messages for each channel from the last committed message (exclusive) * to the current tail. This result returned by this method is somewhat transient in situations where there are * active Subscribers with in-flight commit requests, so the count may change just after the method returns. * Message expiry may also affect the returned value, if messages expire after the count is returned. * * @param sSubscriberGroup the name of the subscriber group * * @return the number of remaining messages for the subscriber group */ default int getRemainingMessages(String sSubscriberGroup) { return getRemainingMessages(sSubscriberGroup, new int[0]); } /** * Returns the number of remaining messages to be read from the topic for the specific subscriber group, * and optionally for one or more specific channels. *

* This method is a sum of the remaining messages for each channel from the last committed message (exclusive) * to the current tail. This result returned by this method is somewhat transient in situations where there are * active Subscribers with in-flight commit requests, so the count may change just after the method returns. * Message expiry may also affect the returned value, if messages expire after the count is returned. * * @param sSubscriberGroup the name of the subscriber group * @param anChannel one or more optional channels * * @return the number of remaining messages for the subscriber group */ int getRemainingMessages(String sSubscriberGroup, int... anChannel); /** * Return the {@link TopicService} managing this {@link NamedTopic}. * * @return the {@link TopicService} managing this {@link NamedTopic} */ default TopicService getTopicService() { return (TopicService) getService(); } // ----- inner interface: ElementCalculator ----------------------------- /** * A unit calculator is an object that can calculate the cost of * storing an element in a topic. */ interface ElementCalculator { /** * Calculate cost for the specified element. * * @param binElement the element value (in serialized Binary form) to evaluate for unit cost * * @return an integer value 0 or greater, with a larger value * signifying a higher cost * * @throws IllegalArgumentException if the specified object type * cannot be processed by this calculator */ int calculateUnits(Binary binElement); /** * Obtain the name of the unit calculator. This is intended to be * human-readable for use in a monitoring tool; examples include * "SimpleMemoryCalculator" and "BinaryMemoryCalculator". * * @return the name of the unit calculator */ default String getName() { return ClassHelper.getSimpleName(getClass()); } } // ----- constants ------------------------------------------------------ /** * The topic should have the default number of channels. */ int DEFAULT_CHANNEL_COUNT = 0; /** * The default capacity of pages when using the default binary calculator (1MB). */ long DEFAULT_PAGE_CAPACITY_BYTES = 1024*1024; /** * The default subscriber timeout. */ Seconds DEFAULT_SUBSCRIBER_TIMEOUT_SECONDS = new Seconds(300); /** * The default reconnect timeout. */ Seconds DEFAULT_RECONNECT_TIMEOUT_SECONDS = new Seconds(300); /** * The default reconnect retry. */ Seconds DEFAULT_RECONNECT_RETRY_SECONDS = new Seconds(5); /** * The default reconnect wait. */ Seconds DEFAULT_RECONNECT_WAIT_SECONDS = new Seconds(10); }