This chapter discusses the following topics:
Background About How Notification Works
Subscribing to Receive Notifications
Managing the Notification Process
Background About How Notification Works
This section provides information about how the notification system works. It covers these topics:
In Release 1.3, only one session is allowed in a single Java VM, so only one session can subscribe to a notification. In a future release, it is expected that there can be multiple sessions in the same Java VM. In this release, separate processes can simultaneously subscribe to receive notifications for the same locations.
When there is an event that involves the location in a notification, the application uses the notification API to send the notification to the ObjectStore Server.
When the Server receives a notification, it determines which sessions are subscribed for that notification. The Server then queues messages to be sent to the receiving sessions. The Server returns the number of messages queued and then asynchronously sends notifications to the Cache Manager of the receiving sessions (the subscribers).
There is a queue inside the Cache Manager for each session on that host. When the Cache Manager receives a notification from the Server, it puts the notification into the queue of each of the subscribing sessions.
A session that subscribes to one or more notifications usually dedicates a thread to receive notifications. When this thread finds a notification in the Cache Manager's queue for that session, it removes the notification from the queue and returns it to the associated session, which performs an application-specific action.
When a session receives a notification, it performs an application-specific action. For example, it might post a Windows message, modify the application's transient data structures, or otherwise queue the notification for processing by another thread. It then waits for the next notification.
The thread dedicated to receiving notifications typically does very little work. It might do queue management, for example, maintaining a priority queue of notifications for another thread, or coalescing similar notifications. However, processing should be minimal, so the Cache Manager notification queue does not overflow. Queue overflow can happen if many notifications arrive in quick succession. The thread receiving the notifications might not be able to keep up with the process of removing the notification from the queue and returning it to the session.
In contrast to most other ObjectStore APIs, Notification.receive() is not locked out when other threads are in ObjectStore operations. If the thread does not access persistent data or call other ObjectStore APIs, it can run entirely asynchronously.
The sending of commit-time notifications, however, is closely integrated with transactions. ObjectStore queues commit-time notifications inside a transaction, and sends them when the transaction commits. If the transaction aborts, the application never sends the commit-time notifications. This is useful when you want dispatch of the notification to be contingent on a database modification that becomes visible when a transaction commits.
There are no restrictions on transaction types. The enclosing transaction can be read-only or update. Databases can be opened read-only, update, or MVCC.
As always, database changes made by a session are not visible to other sessions until the transaction commits. Therefore, all notifications that indicate changes to persistent data should be made at commit time.
Within a database, notifications are not integrated with ObjectStore security. A session can subscribe to notifications and send notifications that reference database locations in any segment.
You can specify a Java peer object if it identifies a persistent C++ object. See Developing ObjectStore Java Applications That Access C++, Chapter 3, Writing the Application.
The kind, data, and message parameters provide information about the event. Every notification has a kind parameter. If you specify a negative argument, ObjectStore throws IllegalArgumentException.
String a = null; new Notification(foobar, 102, a); new Notification(foobar, 102);If you do specify a third argument, it is a sequence of bytes. For convenience, ObjectStore allows you to pass in a Java String instead of a sequence of bytes. ObjectStore uses UTF-8 encoding to encode message arguments into a sequence of bytes.
When ObjectStore sends a notification, it makes the kind parameter and the data or message parameter, if there is one, available to subscribers. If a notification includes a null string ("null"), it is received as an empty string ("").
To do so, you must ensure that the reference is not to a stale object. If it is, ObjectStore throws ObjectException.
To ensure a nonstale object, you can evict the referenced object or commit or abort the transaction with a retain type other than ObjectStore.RETAIN_STALE. If you evict the object so that you can still use it, but then you abort or commit the transaction with ObjectStore.RETAIN_STALE, this cancels the retain type specified for evict().
public static final int MAXIMUM_DATA_LENGTH = 16383For the String message parameter, this variable specifies the maximum length of the UTF-8 encoding of the string. If the String is ASCII, the compression is one-to-one.
The placement parameter can specify a database or segment. The subscribing session receives a notification if the application sends a notification that refers to an object in the specified segment or database.
The location parameter specifies a persistent object.
A session can subscribe to many locations, segments, and databases simultaneously. ObjectStore stores subscriptions in the ObjectStore Server for as long as the corresponding database is open for the associated session.
If you try to unsubscribe from a notification that you are not subscribed to, nothing happens.
The only way to cancel a segment or database subscription is to unsubscribe from that segment or database. You cannot unsubscribe from a segment or database by unsubscribing from the notifications about the objects in that segment or database.
The object referenced in the notification cannot be stale and cannot have been destroyed.
Modification of an object does not cause a notification to be sent. A notification is sent only when the application program explicitly uses the notification API to send one.
public static Notification receive(int timeout)The timeout parameter specifies the number of milliseconds to wait for a notification. Specify ObjectStore.WAIT_FOREVER to instruct the thread to wait forever. A value of 0 instructs the thread to return if there are no notifications in the queue.
The method returns a Notification object, or null, if there are no notifications in the allotted time. When the timeout parameter is ObjectStore.WAIT_FOREVER, ObjectStore never returns null.
When you call receive(), it does not matter whether or not a transaction is in progress. However, the thread from which you call receive() must be associated with a session.
A thread that calls the Notification.receive() method allows you to avoid polling your application. This method returns as soon as a notification is available, and until then it just waits. No polling is involved. The application is awakened when a notification arrives.
Nothing forces a session to retrieve or read notifications. A session can subscribe to notifications but never retrieve any.
To avoid resource exhaustion in the Cache Manager, the size of the notification queue for each client is fixed. If the Cache Manager receives a notification and the queue is full, ObjectStore discards the notification. This is called an overflow. Overflows do not cause any exception to be signaled and do not cause the application, the Cache Manager, or the Server to crash.
The Cache Manager keeps statistics on the notification queue that include
You can also use the ObjectStore utility oscmstat to obtain these statistics. The ossvrstat utility displays statistics on the number of notifications received and sent by the Server. See Chapter 4 in ObjectStore Management.
Retrieving notifications only accesses shared memory and is very fast. If a session does not retrieve its notifications, the Cache Manager can run out of queue space. This causes the Cache Manager to discard notifications.
Every call to subscribe(), unsubscribe(), notifyImmediate(), and notifyOnCommit() requires one round-trip message to the ObjectStore Server.
If any commit-time notifications are queued during a transaction, there is an additional remote procedure call (RPC) to the ObjectStore Server during the commit operation.
Notifications are stored and forwarded in the Server, Cache Manager, and sometimes even in the receiving application. Therefore, delivery of notifications might not be particularly fast. Performance varies according to system load and the amount of notification processing. For example, delivery could range from milliseconds to several seconds.
As a general rule, if you plan your application to use notifications, you should not expect high throughput. Do not expect a client application to send or receive more than about ten notifications per second. In other words, do not use ObjectStore notification to meet high-speed requirements. The notification facility has a fairly simple design with limited buffering capability.
Updated: 10/07/98 08:46:23