eBus v. 3.1.0
NOTE: eBus v. 3.1 contains code-breaking changes due to a
need to simplify message processing and improve eBus
performance.
Overview: The release goal was to noticeably improve eBus
performance by reducing the number of "bookkeeping"
classes and, in turn, reducing the number of instances.
eBus classes now fall into two categories: subjects and handles. There are two subject classes: 1. ESubject: for notification messages. 2. ERequestSubject: for request messages. There are five handle classes: 1. ESubjectAd: a notification subject advertisement. 2. ESubscription: a notification subject subscription. 3. ERequestAd: a request subject advertisement. 4. ERequestSubscription: a request subject subscription (new). 5. ERequest: a request instance. eBus handles are cookies used to store eBus bookkeeping information necessary for message routing. Since these objects were created anyway, it made sense to move the bookkeeping information into the handles and drop the private bookkeeping classes. Since these handles contain the information needed for message routing, they are now used as subject method parameters instead of the EPublisher/ESubscription/ERequestor/EReplier instance. This improves message routing performance. ERequestSubscription is introduced to improve eBus request performance. If an eBus client will be making more than one request against a particular request subject, then it should "subscribe" to that subject by calling: sub = ERequest.subscribe(EMessageKey, ERequestor) The purpose behind this call is to do most of the necessary request bookkeeping once and then only a minimal of bookkeeping for the request: request = ERequest.request(ERequestMessage, sub); EClient is a new class which tracks each eBus client's advertisements, subscriptions, and requests. It also contains a single-threaded executor for making callbacks to the client. An eBus client is considered live if it has at least one active advertisement or subscription or request. When this is no longer the case, the EClient instance is shutdown.
.Net Update Delayed
The latest eBus design requires significant .Net changes.
Consequently, this means that the .Net update will appear
at a later date.
net.sf.eBus.client:
AbstractSubject:
Moved ESubject data members to this class as part of creating
an ERequestSubject class which also extends AbstractSubject.
Dropped EDispatcher and ETask classes and replaced with a one single-threaded executor per live eBus client. An eBus client is considered live if it has at least one active advertisement or subscription or request. If this is not the case, the eBus client is considered dead and its executor is shutdown.
EAdvertisement:
Extends EHandle class.
Stores the message key as a compiled regular expression Pattern used to match the advertisement to subject message keys. Stores the advertisement "local only" flag. If true, then the advertisement is *not* forwarded to remote applications.
EClient:
New class for tracking the eBus clients active
advertisements, subscriptions, and requests. Maintains the
single-threaded executor for executing client callback tasks.
EDispatcher:
Deleted.
EFeed:
Removed lock since EFeedMap is now concurrent.
Removed support for an unsent message queue.
EFeedMap:
Implements ConcurrentMap rather than Map.
Added method advertisement(EMessageKey) which returns only the advertisement associated with the message key. Removed support for an unsent message queue.
EHandle:
New class which is the base class for eBus advertisements,
subscriptions, and requests. Stores a reference to its
EClient instance and the handle message key.
ERemoteApp:
Minimized "synchronized" block use with ConcurrentHashMaps
and atomics. Minimized remaining "synchronized" blocks to
protect only the critical section data.
ERequest:
Changed base class from AbstractSubject to EHandle because
a request is not a subject. Created new ERequestSubject class
for that purpose.
Added subscribe method which allows requestors to "subscribe" to a request subject to which they will be placing multiple requests. The returned subscription can then be used to post requests. The goal is to do most of the request bookkeeping when subscribing and the remaining, minimal bookkeeping when making the subscription. Changed the reply and cancelReply by replacing the EReplier parameter with EAdvertisement. This was done as part of the effort to minimize bookkeeping classes and improve performance. Minimized "sychronized" block use and size by using concurrent collections and atomics.
ERequestAd:
Stores the optional advertisement ECondition, the list of
matched request subjects, and the list of currently active
requests handled by this advertisement.
ERequestSubject:
This new class extends AbstractSubject and does the work of
tracking request advertisements and subscriptions. This work
was previously done by ERequest when it extends
AbstractSubject.
ERequestSubscription:
This new class extends AbstractSubscription and is used to
reduce request processing time when making multiple requests
against the same subject.
ESubjectAd:
Tracks the feed information status for each matched
notification subject. This includes:
+ The number of subscribers.
+ The publisher feed status (up or down) and status reason.
ESubscription:
Stores the notification subscription optional ECondition.
Tracks the publishers currently publishing to this
subscription.
ETask:
Deleted.
net.sf.eBus.client.sysmessages:
CancelRequest:
Removed field "public final int requestId" since it is no
no longer used by the remote eBus application.
RemoteRequest:
Deleted since request identifier is no longer needed by
remote eBus application. The request message itself is
transmitted to the remote application.
net.sf.eBus.comm:
EConnection:
Corrected "close upon final transmission" logic by adding a
state data member and ConnectState enum.
Input is thrown away when the connection is in the closing state.
net.sf.eBus.messages:
EMessageHeader:
Added messageKey method to return the encapsulated message
key.
EMessageKey:
Added boolean methods isNotification and isRequest which
report whether the message key is for a notification or
request message.
net.sf.eBus.messages.type:
DataType:
Dropped type name and reverse type maps.
Replaced explicit locking with concurrent hash map.
FileType:
Changed maximum file name length from 8,132 characters to
1,024 characters.
net.sf.eBus.net:
AsyncServerSocket:
Server socket channel is now configured to be non-blocking.
AsyncSocket:
Socket channel is now configured to be non-blocking.
The send method will now immediately send the output if the output buffer is empty when send is called. An empty output buffer means that output transmission is not in the hands of the SelectorThread. A non-empty output buffer means that output transmission has been passed to SelectorThread.
SelectorThread:
Added a volatile boolean pending flag. Only when this flag is
true should the pending lock be acquired. If false, then
there are no pending invocations and so the lock does not
need to be acquired.