public interface PublishingTopicData extends TopicData, TopicDataWithMetadata
Once associated with a topic the data may be updated using
update(TopicMessage)
or one of the implementation specific update
methods. Before data can be updated it must be locked for update using
startUpdate()
. One or more updates may then be performed and if
differences have been detected then a delta message containing only those
differences can be published to subscribed clients as shown in the example
below:
data.startUpdate(); try { data.update(message); if (data.hasChanges()) { data.publishMessage(data.generateDeltaMessage()); } } finally { data.endUpdate() }The start/endUpdate block is atomic in that either all updates will be applied or none will be applied. An exception in an update method will cause all updates to be discarded by the endUpdate. Also you can explicitly discard updates using
abortUpdate()
.
The try/finally pattern shown in the above example should always be used to
ensure that locks are not held indefinitely. For the simple case where a
single update is required and a delta is to be published as it is generated
to all subscribed clients the convenience method
updateAndPublish(TopicMessage)
is provided which encapsulates the
above processing.
Modifier and Type | Method and Description |
---|---|
void |
abortUpdate()
Allows an update to be aborted.
|
boolean |
addListener(TopicDataListener listener)
Adds a (@link TopicDataListener listener} for changes to the topic data.
|
String |
asString()
Renders the state of the data as a String.
|
void |
endUpdate()
Ends an update and unlocks the topic.
|
TopicMessage |
generateAckDeltaMessage(String... headers)
As
generateDeltaMessage(String...) but generating a message that
requires acknowledgement. |
TopicMessage |
generateDeltaMessage(String... headers)
Generates a
delta message summarising
changes to the data since updating was started (startUpdate()
was called). |
TopicDataInitialiser |
getInitialiser()
Returns data initialiser.
|
long |
getLastUpdateTimeMillis()
Returns the time that the data was last updated (in milliseconds).
|
String[] |
getLoadHeaders()
Returns any load headers set (see
setLoadHeaders(String...) ). |
TopicMessage |
getLoadMessage()
This returns the current data state as a
load message. |
boolean |
hasChanges()
This can be called during an update block to determine whether the data
has been updated.
|
boolean |
hasSlaves()
Does this topic data currently have any
slaves . |
void |
initialise(TopicMessage message)
Initialises the data from a supplied message.
|
boolean |
isDeltaAckRequired()
Indicates whether
delta messages generated
will require acknowledgment (see setLoadAckRequired(boolean) . |
boolean |
isLoadAckRequired()
Indicates whether
load messages
generated will require acknowledgement (see
setLoadAckRequired(boolean) . |
boolean |
isSlave()
Deprecated.
since 5.5 as it provides not information over the topic data
type
|
void |
publishExclusiveMessage(TopicMessage message,
TopicClient client)
As
publishMessage(TopicMessage) but excluding a specified
client. |
void |
publishExclusiveMessage(TopicMessage message,
TopicClient client,
MessagePriority priority)
As
publishExclusiveMessage(TopicMessage, TopicClient) but
allowing a message priority to be specified. |
void |
publishMessage(TopicMessage message)
Publish a message (at
normal priority) to
all subscribed clients. |
void |
publishMessage(TopicMessage message,
MessagePriority priority)
As
publishMessage(TopicMessage) but allowing a message priority
to be specified. |
boolean |
removeListener(TopicDataListener listener)
Removes a
TopicDataListener . |
void |
setDeltaAckRequired(boolean ackRequired)
This may be used to indicate that when a
delta message is generated it should have
ackRequired set. |
void |
setInitialiser(TopicDataInitialiser initialiser)
Allows an object to be assigned that will be responsible for initialising
the data just prior to its attachment to a topic.
|
void |
setLoadAckRequired(boolean ackRequired)
This may be used to indicate that when a
load message is generated it should
have ackRequired set (see
getLoadMessage() ). |
void |
setLoadHeaders(String... headers)
This may be used to set user headers to be applied to a
load message when it is generated (see
getLoadMessage() ). |
void |
startUpdate()
Locks the parent topic in preparation for updates.
|
boolean |
update(TopicMessage message)
Updates the data with the data from a supplied message.
|
boolean |
updateAndPublish(TopicMessage message)
Convenience method to perform an atomic update and publish a delta
message if any changes are detected.
|
boolean |
updateAndPublish(TopicMessage message,
MessagePriority priority)
As
updateAndPublish(TopicMessage) but allowing a message
priority to be specified. |
void |
updateAndPublishFromDelta(TopicMessage message)
This method allows the topic data to be updated using input that
represents only deltas of change to the topic.
|
getDeltaEncoding, getLoadEncoding, getLoadMessage, getTopic, getType, hasSubscribers, isCommand, isLockedByCurrentThread, isPaged, isPublishing, isRouting, isService, lock, setDeltaEncoding, setLoadEncoding, unlock
getMetadataNode, isMetadataMandatory, setMetadataNode
void setLoadHeaders(String... headers) throws APIException
load
message when it is generated (see
getLoadMessage()
).
When headers are set in this way then they will be used for all load messages subsequently generated.
headers
- specifying null indicates that no user headers are
requiredAPIException
- if unable to set the headersString[] getLoadHeaders()
setLoadHeaders(String...)
).void setLoadAckRequired(boolean ackRequired) throws APIException
load
message is generated it should
have ackRequired
set (see
getLoadMessage()
).
By default ackRequired is not set on load Messages.
This setting will apply to all load messages subsequently generated (until called again).
ackRequired
- true to indicate that the next and subsequent load
message generated should have the 'ackRequired' flag set, false to
indicate that it should not be setAPIException
- if unable to set the ackRequired flagboolean isLoadAckRequired()
load
messages
generated will require acknowledgement (see
setLoadAckRequired(boolean)
.void setDeltaAckRequired(boolean ackRequired) throws APIException
delta
message is generated it should have
ackRequired
set.
This option may be used to request ack for all delta messages generated
rather than using generateAckDeltaMessage(String...)
for every
message. If this is set then the generateDeltaMessage(String...)
will generate messages requiring acknowledgment.
ackRequired
- true to indicate that the next and subsequent delta
generated should have the 'ackRequired' flag set, false to
indicate that it should not be setAPIException
- if unable to set the ackRequired flagboolean isDeltaAckRequired()
delta
messages generated
will require acknowledgment (see setLoadAckRequired(boolean)
.
TopicMessage getLoadMessage() throws APIException
load
message.
This may be used when a client subscribes to return the current state.
This may only be called after the data has been initialised and associated with a topic.
A load message is cached for repeat calls, so the returned message should not be changed in any way.
Whenever an update occurs the cached load message is recreated.
If user headers are required by load messages generated by this method
then they must be set using setLoadHeaders(String...)
.
If acknowledgement is required on load messages generated by this method
then this should be indicated using setLoadAckRequired(boolean)
.
The returned message will positioned at the start of the data ready for reading.
getLoadMessage
in interface TopicData
APIException
- if the data has not been attached to a topic or
generation of a load message failsboolean update(TopicMessage message) throws APIException
The message will be parsed according to the topic data type.
It is assumed that the message input (even if it is a delta) contains a representation of the full state of the topic.
If the specified message is a delta
then
it is parsed and compared against the current data state. Only
differences will be used to populate the generated delta message (see
generateDeltaMessage(String...)
) and if there are no differences
then no delta would be required (see hasChanges()
).
If the specified message is a TopicMessage.isTopicLoad()
message
then it will entirely replace the existing data and the delta generated
will represent the total state.
This may only be called from within an update block (see
startUpdate()
).
The message does not need to be rewound before calling this method and on successful exit from the method the position will be the same as it was on entry.
message
- the message to update the data from.APIException
- if unable to perform the update. After such an
exception the update can not continue and when
endUpdate()
is called the data state will be reverted to
its state before startUpdate()
was calledboolean updateAndPublish(TopicMessage message) throws TimeoutException, APIException
This starts an update block, updates the data from the supplied message, publishes a delta message to all subscribed clients if there have been changes and then ends the block. This single call is therefore equivalent to the following code:
data.startUpdate(); try { data.update(message); if (data.hasChanges()) { if (message.isDelta()) { data.publishMessage(data.generateDeltaMessage()); } else { data.publishMessage(data.getLoadMessage()); } } } finally { data.endUpdate() }This can therefore be used when only a single update is required and the resulting message can be published to all subscribed clients as it is generated.
If the supplied message is a load message then the data is re-initialised and a load message is published.
As with update(TopicMessage)
this method assumes that the input
message contains a full representation of the state of the topic. Where
if is required to apply partial updates (for example to process delta
messages received from upstream master servers) then
updateAndPublishFromDelta(TopicMessage)
should be used.
message
- the input messageTimeoutException
- if the lock
timeout
period for the topic has been exceeded whilst waiting to
obtain a lock on the dataAPIException
- if the update or publish failed. If this occurs then
the data will still be in the state it was before this callvoid updateAndPublishFromDelta(TopicMessage message) throws TimeoutException, APIException
This is similar to updateAndPublish(TopicMessage)
except that
when delta
messages are input it is
assumed that they represent only a delta of change to the topic. For some
topic types there is no difference in processing between this and
updateAndPublish(TopicMessage)
but for those that support
partial deltas it allows a partial delta to be applied. This is therefore
useful in the case where the updates to the topic are actually coming as
partial deltas from an upstream instance of the topic (e.g. an instance
in a master server where this instance is in a slave server).
If the input message is a delta then the changes are simply applied to the current state and the delta is then published to all subscribers. No comparisons are made between the current state values and those input in order to determine output delta values. Therefore, if the input delta did contain the full topic state then output delta would also contain the full state regardless of current state of the topic data.
If the input message is a load
message
then the state is simply replaced and the load published to all
subscribers. The effect therefore being exactly the same as if
updateAndPublish(TopicMessage)
had been called with the load
message.
message
- the input messageTimeoutException
- if the lock
timeout
period for the topic has been exceeded whilst waiting to
obtain a lock on the dataAPIException
- if the update or publish failed. If this occurs then
the data will still be in the state it was before this callboolean updateAndPublish(TopicMessage message, MessagePriority priority) throws TimeoutException, APIException
updateAndPublish(TopicMessage)
but allowing a message
priority to be specified.message
- the input messagepriority
- the message priorityTimeoutException
- if the lock
timeout
period for the topic has been exceeded whilst waiting to
obtain a lock on the dataAPIException
- if publish failedTopicMessage generateDeltaMessage(String... headers) throws APIException
delta
message summarising
changes to the data since updating was started (startUpdate()
was called).
The returned message will positioned at the start of the data ready for reading.
headers
- optional header values to write to the messagehasChanges()
would return falseAPIException
- if an error occurs whilst generating the delta
messageTopicMessage generateAckDeltaMessage(String... headers) throws APIException
generateDeltaMessage(String...)
but generating a message that
requires acknowledgement.
The returned message will positioned at the start of the data ready for reading.
headers
- optional header values to write to the messagegenerateDeltaMessage(String...)
APIException
- if an error occurs whilst generating the delta
messageboolean hasChanges()
If called outside the scope of an update then this would always return
false. This will only return true if within an update block where updates
to the data have occurred that require a delta message and so a call to
generateDeltaMessage(String...)
would return a message that
could be sent to all clients using publishMessage(TopicMessage)
.
generateDeltaMessage(String...)
. This will return false
if called outside an update block or within a block where update
errors have occurredvoid publishMessage(TopicMessage message) throws APIException
normal
priority) to
all subscribed clients.
This may only be called from within an update block. In previous releases this was not enforced. From release 5.6, an error message will be logged the first time that this method is called outside an update block. In future releases, an exception will be thrown.
If this topic data has slaves
, then the
message will be published on this topic first and then an equivalent
message on all of the slave topics in turn.
message
- the message to publishAPIException
- if unable to publish the message. This will occur
if the data is not yet associated with a topic or the topic is
deleted.void publishMessage(TopicMessage message, MessagePriority priority) throws APIException
publishMessage(TopicMessage)
but allowing a message priority
to be specified.message
- the message to publishpriority
- the message priorityAPIException
- if unable to publish the message. This will occur
if the data is not yet associated with a topic or the topic is
deleted.void publishExclusiveMessage(TopicMessage message, TopicClient client) throws APIException
publishMessage(TopicMessage)
but excluding a specified
client.
message
- the message to publishclient
- the client to excludeAPIException
- if unable to publish the message. This will occur
if the data is not yet associated with a topic or the topic is
deleted.void publishExclusiveMessage(TopicMessage message, TopicClient client, MessagePriority priority) throws APIException
publishExclusiveMessage(TopicMessage, TopicClient)
but
allowing a message priority to be specified.
message
- the message to publishclient
- the client to excludepriority
- the message priorityAPIException
- if unable to publish the message. This will occur
if the data is not yet associated with a topic or the topic is
deleted.@Deprecated boolean isSlave()
slave
.
From release 5.5, SlaveTopicData no longer extends PublishingTopicData, so this method always returns false.
boolean hasSlaves()
slaves
.void initialise(TopicMessage message) throws APIException
This may only be called before the data is associated with a topic.
The message will be parsed according to the data type.
The specified message may be a load
or
a delta
. In either case the total data
state is derived from the parsed data of the message.
message
- the message to initialise the data fromAPIException
- if initialisation fails. If this occurs then the
data will be in an indeterminate statevoid setInitialiser(TopicDataInitialiser initialiser)
This must be called before the data is attached to a topic. If it is set afterwards it will not be invoked.
initialiser
- the initialiserTopicDataInitialiser getInitialiser()
void startUpdate() throws TimeoutException, APIException
This will block waiting to acquire the lock if the data is currently locked by another thread.
The data will remain locked until endUpdate()
or
abortUpdate()
is called.
Care must be taken to ensure that, once locked, data is always unlocked. For example:
data.startUpdate(); try { // do updates } finally { data.endUpdate() }
TimeoutException
- if the lock
timeout
period for the topic has been exceeded whilst waiting to
obtain a lock on the dataAPIException
- if unable to acquire a lock on the data. This can
occur because the topic is already locked for update by the
current threadvoid endUpdate()
If the data has been successfully changed then this will commit those changes and unlock the topic.
If there have been no changes to the data then the topic is simply unlocked.
If there were any failures whilst updating the data then the data will be reverted to its state before the update started and the topic will be unlocked.
If the topic is not currently locked by the current thread then this will simply return.
void abortUpdate()
This will discard any updates to the data since startUpdate()
end release locks on the topic.
If the topic is not currently locked by the current thread then this will simply return.
long getLastUpdateTimeMillis()
String asString()
boolean addListener(TopicDataListener listener)
listener
- the listenerboolean removeListener(TopicDataListener listener)
TopicDataListener
.listener
- the listener to removeCopyright © 2016 Push Technology Ltd. All Rights Reserved.