public final class ERequestFeed extends EFeed implements IERequestFeed
ERequestFeed is the application entry point for
posting request messages to repliers.
Follow these steps to use this feed:
Step 1: Implement the ERequestor
interface.
Step 2:
Open
a request feed for a given ERequestor instance and
type+topic message key.
Step 3 (optional): Do not override
ERequestor interface methods. Instead, set callbacks
using statusCallback(FeedStatusCallback) and/or
replyCallback(ReplyCallback) passing in Java lambda
expressions.
Step 4:
Subscribe to reply message key.
Step 5:
Send a request to one or
more advertised repliers. If there are no advertised repliers,
then request(ERequestMessage) returns
ERequestFeed.RequestState.DONE, signaling that the requestor will
not receive any replies.
Step 6: Wait for
replies
to arrive. When the remaining parameter is zero, that
means this is the final reply from all repliers. When
EReplyMessage.replyStatus is
EReplyMessage.ReplyStatus.ERROR or EReplyMessage.ReplyStatus.OK_FINAL,
then this is the final reply from that replier.
Step 7: A requestor may terminate a request
prior to completion by calling
EFeed.close(). No more replies should
be received once this is done. (Note: there is a possibility
that an in-flight reply will still be posted to the
requestor.)
Step 8: When
requestor is shutting down, retract the
subscription and close the feed.
ERequestFeedimport java.util.ArrayList;
import java.util.List;
import net.sf.eBus.client.EFeed.FeedScope;
import net.sf.eBus.client.ERequestFeed;
import net.sf.eBus.client.ERequestor;
import net.sf.eBus.messages.EMessageKey;
import net.sf.eBus.messages.EReplyMessage;
Step 1: Implement the ERequestor interface.
public class CatalogRequestor implements ERequestor {
public CatalogRequestor(final String subject, final FeedScope scope) {
mKey = new EMessageKey(com.acme.CatalogOrder.class, subject);
mScope = scope;
mFeed = null;
mRequests = new ArrayList<>();
}
@Override
public void startup() {
try {
Step 2: Open request feed.
mFeed = ERequestFeed.open(this, mKey, mScope);
Step 3: ERequestor interface methods overridden.
Step 4: Subscribe to reply message key.
mFeed.subscribe();
} catch (IllegalArgumentException argex) {
// Open failed. Place recovery code here.
}
}
@Override
public void shutdown() {
synchronized (mRequests) {
for (ERequestFeed.ERequest request : mRequests) {
Step 7: Cancel request by closing request.
request.close();
}
mRequests.clear();
}
Step 8: On shutdown, close request feed.
if (mFeed != null) {
mFeed.close();
mFeed = null;
}
}
@Override
public void feedStatus(final EFeedState feedState, final ERequestFeed feed) {
if (feedState == EFeedState.DOWN) {
// Down. There are no repliers.
} else {
// Up. There is at least one replier.
}
}
Step 6: Wait for replies to request.
@Override
public void reply(final int remaining,
final EReplyMessage reply,
final ERequestFeed.ERequest request) {
final String reason = msg.replyReason();
if (msg.replyStatus == EReplyMessage.ReplyStatus.ERROR)
{
// The replier rejected the request. Report the reason
} else if (msg.replyStatus == EReplyMessage.ReplyStatus.OK_CONTINUING) {
// The replier will be sending more replies.
} else {
// This is the replier's last reply.
}
if (remaining == 0) {
synchronized (mRequests) {
mRequests.remove(request);
}
}
}
Step 5: Send a request message.
public void placeOrder(final String product,
final int quantity,
final Price price,
final ShippingEnum shipping,
final ShippingAddress address) {
final CatalogOrder msg =
new CatalogOrder(product, quantity, price, shipping, address);
try {
synchronized (mRequests) {
mRequests.add(mFeed.request(msg));
}
} catch (Exception jex) {
// Request failed. Put recovery code here.
}
}
private final EMessageKey mKey;
private final FeedScope mScope;
private final List<ERequestFeed.ERequest> mRequests;
private ERequestFeed mFeed;
}ERequestor,
EReplier,
EReplyFeed| Modifier and Type | Class and Description |
|---|---|
static class |
ERequestFeed.ERequest
This class represents an individual request, tracking the
current request state and the remaining repliers.
|
static class |
ERequestFeed.RequestState
A request is either not placed, active, done, or canceled.
|
protected static class |
ESingleFeed.FeedType
Enumerates the supported feed types.
|
EFeed.AbstractClientTask, EFeed.FeedScope, EFeed.NotifyTask, EFeed.StatusTask<T extends IEFeed>| Modifier and Type | Field and Description |
|---|---|
static String |
FEED_STATUS_METHOD
ERequestor.feedStatus(EFeedState, ERequestFeed)
method name. |
protected int |
mActivationCount
Tracks the number of contra-feeds matched to this feed.
|
protected static List<EFeed> |
mAdvertisers
Track the advertised feeds in order to generate
advertise messages. |
protected ESingleFeed.FeedType |
mFeedType
Specifies whether this is a publish, subscribe, request,
or reply feed.
|
protected net.sf.eBus.client.ESubject |
mSubject
The feed interfaces with this eBus subject.
|
static String |
REPLY_METHOD
|
mEClient, mFeedId, mFeedState, mInPlace, mIsActive, mScope, NO_CONDITION, NOTIFY_METHOD| Modifier and Type | Method and Description |
|---|---|
int |
activationCount()
Returns the feed activation count.
|
protected void |
inactivate()
Cancels this feed's active requests
|
EMessageKey |
key()
Returns the feed message key.
|
String |
messageSubject()
Returns the feed
message key subect. |
static ERequestFeed |
open(ERequestor client,
EMessageKey key,
EFeed.FeedScope scope)
Creates a new request feed for the given client, message
key, and feed scope.
|
static ERequestFeed |
open(ERequestor cl,
EMessageKey key,
EFeed.FeedScope scope,
EClient.ClientLocation l,
boolean isMulti)
Creates a new request feed for the given client, message
key, and feed scope.
|
void |
replyCallback(Class<? extends EReplyMessage> mc,
ReplyCallback cb)
Sets the callback for a specific reply message class.
|
void |
replyCallback(ReplyCallback cb)
Puts the reply message callback in place
for all reply types.
|
ERequestFeed.ERequest |
request(ERequestMessage msg)
Forwards the request to all matching repliers, returning
the request instance.
|
void |
statusCallback(FeedStatusCallback<ERequestFeed> cb)
Puts the feed status callback in place.
|
void |
subscribe()
Subscribes this request feed to the eBus subject.
|
String |
toString()
Returns a containing the feed message key and data member
values.
|
void |
unsubscribe()
Retracts this request feed from the associated subject.
|
addAllKeys, addKey, checkScopes, clientId, close, defaultDispatcher, eClient, equals, feedId, feedState, findKeys, findKeys, findKeys, hashCode, inPlace, isActive, isFeedUp, isOverridden, loadKeys, location, register, register, register, scope, shutdown, shutdown, shutdownAll, startup, startup, startupAll, storeKeys, storeKeys, storeKeyspublic static final String FEED_STATUS_METHOD
ERequestor.feedStatus(EFeedState, ERequestFeed)
method name.public static final String REPLY_METHOD
protected static final List<EFeed> mAdvertisers
advertise messages.protected final ESingleFeed.FeedType mFeedType
protected final net.sf.eBus.client.ESubject mSubject
feed type.protected int mActivationCount
protected void inactivate()
inactivate in class EFeedpublic void statusCallback(FeedStatusCallback<ERequestFeed> cb)
cb is
not null, feed status updates will be passed to
cb rather than
ERequestor.feedStatus(EFeedState, ERequestFeed).
A null cb results in feed status updates posted to
the
ERequestor.feedStatus(EFeedState, ERequestFeed)
override.statusCallback in interface IERequestFeedcb - feed status update callback. May be
null.IllegalStateException - if this feed is either closed or subscribed.public void replyCallback(ReplyCallback cb)
cb is
not null, replies will be passed to cb
rather than
ERequestor.reply(int, EReplyMessage, ERequestFeed.ERequest).
A null cb results in replies posted to the
ERequestor.reply(int, EReplyMessage, ERequestFeed.ERequest)
override.
Note that this method call overrides all previous calls
to replyCallback(Class, ReplyCallback). If
the goal is to use a generic callback for all replies
except one specific message, then use this method to put
the generic callback in place first and then use
replyCallback(EMessageKey, ReplyCallback).
replyCallback in interface IERequestFeedcb - reply message callback. May be null.IllegalStateException - if this feed is either closed or subscribed.replyCallback(Class, ReplyCallback)public void replyCallback(Class<? extends EReplyMessage> mc, ReplyCallback cb)
cb is not null, replies will be passed to
cb rather than
ERequestor.reply(int, EReplyMessage, ERequestFeed.ERequest).
A cb results in replies posted to the
ERequestor.reply(int, EReplyMessage, ERequestFeed.ERequest)
override.
If the goal is to set a single callback method for all
reply message types, then use
replyCallback(ReplyCallback). Note that method
overrides all previous set reply callbacks.
replyCallback in interface IERequestFeedmc - the reply message class.cb - callback for the reply message.NullPointerException - if mc is null.IllegalArgumentException - if mc is not a reply for this request.IllegalStateException - if this feed is either closed or subscribed.public static ERequestFeed open(ERequestor client, EMessageKey key, EFeed.FeedScope scope)
create new requests.client - the eBus requestor opening this feed.key - the request message key.scope - whether this request matches local repliers,
remote repliers, or both.NullPointerException - if any of the required parameters is null.IllegalArgumentException - if key is not a request message.request(ERequestMessage),
EFeed.close()public void subscribe()
request(ERequestMessage) may be called.subscribe in interface IERequestFeedIllegalStateException - if this feed is closed or the client did not override
ERequestor methods nor put the required callback
in place.unsubscribe(),
EFeed.close()public void unsubscribe()
Note that un-subscribing does not cancel any active requests or prevent delivery of replies to those requests.
unsubscribe in interface IERequestFeedsubscribe(),
EFeed.close()public ERequestFeed.ERequest request(ERequestMessage msg)
IllegalStateException
if no matching repliers are found and, consequently, no
replies will be received. Use the returned
ERequestFeed.ERequest instance to query the request state or
cancel the request.
Note: once the ERequestFeed.ERequest is
returned, the application is responsible for tracking
all active request instances. This request feed does
not store or track requests on behalf of the
application. Closing this requests feed
does not automatically cancel active requests created by
this feed. The application is responsible for canceling
active requests.
msg - send this request message to the repliers.NullPointerException - if msg is null.IllegalArgumentException - if msg does not match the request subject key.IllegalStateException - if there are currently no repliers for this request.EFeed.close()public static ERequestFeed open(ERequestor cl, EMessageKey key, EFeed.FeedScope scope, EClient.ClientLocation l, boolean isMulti)
This method does not parameter validation since this is
a package private method.
cl - the eBus requestor opening this feed.key - the request message key.scope - whether this request matches local repliers,
remote repliers, or both.l - client location.isMulti - true if this is part of a multiple
key feed. If true, this feed is not added to the
client feed list.public String toString()
public final EMessageKey key()
EPublishFeed, then a
notification
message key is returned.public final String messageSubject()
message key subect.public final int activationCount()
Copyright © 2019. All rights reserved.