Class EHistoricSubscribeFeed
- java.lang.Object
-
- net.sf.eBus.feed.historic.EAbstractHistoricFeed<IEHistoricSubscriber>
-
- net.sf.eBus.feed.historic.EHistoricSubscribeFeed
-
- All Implemented Interfaces:
EObject,ERequestor,ESubscriber
public final class EHistoricSubscribeFeed extends EAbstractHistoricFeed<IEHistoricSubscriber> implements ESubscriber, ERequestor
The historic subscriber feed extendsIESubscribeFeed's ability to receive live notification messages with the ability to seamlessly retrieve past notification messages fromhistoric publishers. The historic subscribe feed accomplishes this merge by:-
On start-up, subscribing to live notification and
PublishStatusEventfeeds (the publish status event reports each individual historic publisher status). -
Again on start-up,
requestingpreviously published notification messages from historic publishers if historic subscriber requested them. -
Past notifications contained in
historic repliesand live notifications are placed into a single list with care taken to ensure each message appears only once in the list. -
Once all the replies are received the received
notification message list is sorted by time (millisecond
granularity), publisher identifier, and publisher-set
message position and delivered to
IEHistoricSubscriber.notify(ENotificationMessage, EHistoricSubscribeFeed)one at a time. - After this all live notifications are forwarded to the historic subscriber as the messages arrive.
Note: an historic subscriber may also receives live notification messages from
EPublishers but, of course, none of the previously published messages. Further, an historic subscriber may receive past notification messages from anyrepliersupportingHistoricRequest,HistoricReplymessages.Using Historic Subscribe Feed
Follow these steps for using an historic subscribe feed:
Step 1: Implement
IEHistoricSubscriberinterface.Step 2: Use an
EHistoricSubscribeFeed.Builderinstance (obtained frombuilder(EMessageKey, IEHistoricSubscriber)) to create an historic subscribe feed for a given message key and historic subscriber instance. AnEConditionmay be associated with the feed and only those notification messages matchingmatchthe condition are forwarded to the historic subscriber. If no condition is defined, then all messages are forwarded to the subscriber.Use
EHistoricSubscribeFeed.Builder.doneCallback(HistoricFeedDoneCallback),EHistoricSubscribeFeed.Builder.statusCallback(HistoricFeedStatusCallback)andEHistoricSubscribeFeed.Builder.notifyCallback(HistoricNotifyCallback)to set Java lambda expressions used in place ofIEHistoricSubscriberinterface methods.Step 3:
Start uphistoric subscribe feed. Call this method directly rather than usingEFeed.register(net.sf.eBus.client.EObject)andEFeed.startup(net.sf.eBus.client.EObject)becauseEHistoricSubscribeFeedis an eBus hybrid object and runs in theIEHistoricSubscriber's dispatcher. The underlying live notification and historic notification request feeds are created, subscribed, and historic notification request placed at this time.If the historic subscribe feed has fixed, future end time, a timer is set to terminate the feed at the future time.
Step 4:
Subscribeto open historic feed.Step 5: Wait for
notification messagesandpublisher status eventsto arrive. Note that the historic subscriber receives feed status updates on a per publisher basis rather than for the entire feed. This allows the historic subscriber to know if a particular publisher's notification stream is interrupted.Step 6: When the historic subscribe feed reaches a fixed end point (see more on setting historic subscribe feed intervals below),
IEHistoricSubscriber.feedDone(EHistoricSubscribeFeed.HistoricFeedState, EHistoricSubscribeFeed)is called to let the historic subscriber know that the feed is ended and no more callbacks will be issued. This is not the case if the historic subscribe feed end time is set to on-going.Step 7: When the historic subscriber is shutting down,
shutdownthe feed.Example use of
EHistoricSubscribeFeedimport java.time.Instant; import net.sf.eBus.client.EFeed.FeedScope; import net.sf.eBus.client.EFeedState; import net.sf.eBus.feed.historic.IEHistoricSubscriber; import net.sf.eBus.feed.historic.EHistoricSubscribeFeed; import net.sf.eBus.feed.historic.EHistoricSubscribeFeed.HistoricFeedState; import net.sf.eBus.messages.EMessageKey; import net.sf.eBus.messages.ENotificationMessage; import net.sf.eBusx.time.EInterval.Clusivity; Step 1: Implement the IEHistoricSubscriber interface. public class CatalogSubscriber implements IEHistoricSubscriber { // Subscribe to this notification message class/subject key and feed scope. private final EMessageKey mKey; private final FeedScope mScope; // Catalog subscriber name used for logging purposes. private final String mName; // Request historic messages from this time in the past // (inclusive) to a fixed time in the future (exclusive). private final Instant mBeginTime; private final Instant mEndTime; // Store the feed here so it can be used to unsubscribe. private EHistoricSubscribeFeed mFeed; public CatalogSubscriber(final String subject, final FeedScope scope, final String name, final Instant beginTime, final Instant endTime) { mKey = new EMessageKey(CatalogUpdate.class, subject); mScope = scope; mName = name; mBeginTime = beginTime; mEndTime = endTime; mFeed = null; } @Override public void startup() { try { Step 2: Open the EHistoricSubscribe feed. final EHistoricSubscribeFeed.Builder builder = EHistoricSubscribeFeed.builder(mKey, this); // This subscriber has no associated ECondition and uses IEHistoricSubscriber interface method overrides. mFeed = builder.name(mName) .scope(mScope) .from(mBeginTime, Clusivity.INCLUSIVE) .to(mEndTime, Clusivity.EXCLUSIVE) .build(); Step 3: Start the feed. mFeed.startup(); Step 4: Subscribe to the feed. mFeed.subscribe(); } catch(IllegalArgumentException argex) { // Feed open failed. Place recovery code here. } } Step 7: When subscriber is shutting down, retract subscription feed. @Override public void shutdown() { // mFeed.unsubscribe() is not necessary since close() will unsubscribe. if (mFeed != null) { mFeed.close(); mFeed = null; } } Step 5: Wait for feed status events and notifications to arrive. @Override public void feedStatus(final PublishStatusEvent msg, final EHistoricSubscribeFeed feed) { Publisher feed status handling code here. } @Override public void notify(final ENotificationMessage msg, final EHistoricSubscribeFeed feed) { Notification handling code here. } Step 6: Wait for historic subscribe feed to complete. @Override public void feedDone(final HistoricFeedState feedState, final EHistoricSubscribeFeed feed) { Feed completion code here. } }Setting historic subscribe feed interval
An historic subscribe feed may be set to cover the following time intervals:
-
EHistoricSubscribeFeed.Builder.from(Instant, EInterval.Clusivity)andend timesin thepast. The historic subscribe feed only requests past notification messages for this time interval and does not subscribe to live notification feeds. Once the feed delivers historic notifications, the feed terminates, callingfeedDone. Note that begin time must be prior to end time. -
All historic notification messages from
begintime untilnow. The historic subscribe feed operates in the same manner as above when begin and end time are in the past. -
Begin timein thepastandend timein thefuture. Historic subscribe feed requests past notification messages from begin time until now and subscribes to live notification feeds. Feed sets a timer expiring at the fixed end time. When timer expires, callsIEHistoricSubscriber.feedDone(EHistoricSubscribeFeed.HistoricFeedState, EHistoricSubscribeFeed). -
All live notification messages from
nowuntil afixed future end time. Historic subscribe feed subscribes to live notification feeds only. Sets timer to expire when end time is reached. CallsIEHistoricSubscriber.feedDonewhen timer expires. -
All live notification messages from
nowwithnot fixed end time. This is essentially the same as aIESubscribeFeedwith the exception that feed status updates are per publisher. Historic subscribe feed does not terminate until historic subscribershuts downthe feed.
When an historic subscriber requests past and live notification messages, the historic subscribe feed attempts to make sure the message stream does not contain redundant or missing messages. But message stream correctness cannot be guaranteed.
- Author:
- Charles W. Rapp
- See Also:
IEHistoricSubscriber,IESubscribeFeed,PublishStatusEvent
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classEHistoricSubscribeFeed.BuilderBuilder is used to instantiateEHistoricSubscribeFeedinstances.static classEHistoricSubscribeFeed.HistoricFeedStateEnumerates historic subscribe feed states.static classEHistoricSubscribeFeed.PastComparatorComparator used to sort historic notification messages by timestamp, publisher identifier, and message position.static classEHistoricSubscribeFeed.TimeLocationDenotes if a timestamp denotes the past, current time, future, or future on-going.
-
Field Summary
Fields Modifier and Type Field Description static StringDEFAULT_SUBSCRIBE_FEED_NAMEIf historic publish feed name is not set, then defaults to "EHistoricSubscribeFeed-" appended with feed index.-
Fields inherited from class net.sf.eBus.feed.historic.EAbstractHistoricFeed
mFeedState, mInPlace, mIsOpen, mKey, mName, mOwner, mRequestKey, mScope, mStatusKey
-
Fields inherited from interface net.sf.eBus.client.EObject
NAME_NOT_SET
-
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description EInterval.ClusivitybeginClusivity()Returns begin time clusivity.EHistoricSubscribeFeed.TimeLocationbeginLocation()Returns begin time location.InstantbeginTime()Returns begin time.static EHistoricSubscribeFeed.Builderbuilder(EMessageKey key, IEHistoricSubscriber subscriber)Returns a new historic subscribe feed builder for the specified notification message key and historic subscriber.protected voiddoClose()Closes subordinate notification and request feeds, if open.EInterval.ClusivityendClusivity()Returns end time clusivity.EHistoricSubscribeFeed.TimeLocationendLocation()Returns end time location.InstantendTime()Returns end time.ExceptionerrorCause()Returns exception which causes anEHistoricSubscribeFeed.HistoricFeedState.DONE_ERRORhistoric subscribe feed state.Stringname()Returns historic subscribe feed's eBus object name.voidshutdown()Closes subordinate feeds if open.voidstartup()Places subordinate live notification and publisher status subscriptions (if needed) and requests historic notification messages (again, if needed).EHistoricSubscribeFeed.HistoricFeedStatestate()Returns current historic subscribe feed state.voidsubscribe()Puts historic notification request and live notification feeds in place.-
Methods inherited from class net.sf.eBus.feed.historic.EAbstractHistoricFeed
close, closeFeed, feedState, inPlace, isOpen, key, publisherStatusKey, requestKey, scope
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface net.sf.eBus.client.ERequestor
feedStatus, reply
-
Methods inherited from interface net.sf.eBus.client.ESubscriber
feedStatus, notify
-
-
-
-
Field Detail
-
DEFAULT_SUBSCRIBE_FEED_NAME
public static final String DEFAULT_SUBSCRIBE_FEED_NAME
If historic publish feed name is not set, then defaults to "EHistoricSubscribeFeed-" appended with feed index.- See Also:
- Constant Field Values
-
-
Method Detail
-
doClose
protected void doClose()
Closes subordinate notification and request feeds, if open.- Specified by:
doClosein classEAbstractHistoricFeed<IEHistoricSubscriber>
-
name
public String name()
Returns historic subscribe feed's eBus object name. Used for logging purposes only.
-
startup
public void startup()
Places subordinate live notification and publisher status subscriptions (if needed) and requests historic notification messages (again, if needed). If this feed has a fixed, future end time, then sets timer to expire at that end time.
-
shutdown
public void shutdown()
Closes subordinate feeds if open.
-
beginLocation
public EHistoricSubscribeFeed.TimeLocation beginLocation()
Returns begin time location.- Returns:
- begin time location.
-
beginTime
@Nullable public Instant beginTime()
Returns begin time. If begin time location isEHistoricSubscribeFeed.TimeLocation.NOW, then returnsnull.- Returns:
- begin time. May return
null.
-
beginClusivity
public EInterval.Clusivity beginClusivity()
Returns begin time clusivity. Does not returnnull.- Returns:
- non-
nullbegin time clusivity.
-
endLocation
public EHistoricSubscribeFeed.TimeLocation endLocation()
Returns end time location.- Returns:
- end time location.
-
endTime
@Nullable public Instant endTime()
Returns end time. If end time location is eitherEHistoricSubscribeFeed.TimeLocation.NOWorEHistoricSubscribeFeed.TimeLocation.ON_GOING, then returnsnull.- Returns:
- end time. May return
null.
-
endClusivity
public EInterval.Clusivity endClusivity()
Returns end time clusivity. Does not returnnull.- Returns:
- non-
nullend time clusivity.
-
state
public EHistoricSubscribeFeed.HistoricFeedState state()
Returns current historic subscribe feed state. IfEHistoricSubscribeFeed.HistoricFeedState.DONE_ERRORis returned, then the exception causing this error may be accessed viaerrorCause().- Returns:
- historic subscribe feed state.
- See Also:
errorCause()
-
errorCause
@Nullable public Exception errorCause()
Returns exception which causes anEHistoricSubscribeFeed.HistoricFeedState.DONE_ERRORhistoric subscribe feed state. Returnsnullif there was no such error.- Returns:
- exception causing error feed state.
-
subscribe
public void subscribe()
Puts historic notification request and live notification feeds in place. If feed end time is in the past, then only historic notifications are requested. If begin time starts at the current time, then only live notification subscription is placed.Does nothing if historic subscribe feed already has subordinate feeds in place.
- Throws:
IllegalStateException- if this feed is not open.
-
builder
public static EHistoricSubscribeFeed.Builder builder(EMessageKey key, IEHistoricSubscriber subscriber)
Returns a new historic subscribe feed builder for the specified notification message key and historic subscriber.- Parameters:
key- subscribed notification message key.subscriber- historic subscriber associated with this feed.- Returns:
- new historic subscribe feed builder.
- Throws:
NullPointerException- ifkeyorsubscriberisnull.IllegalArgumentException- ifkeyis not a notification message.
-
-