Figure 1‑1 shows the components of the queued message facility.Figure 1‑1 Queued Service InvocationThe Oracle Tuxedo administrator is responsible for defining servers and creating queue spaces and queues like those shown between the vertical dashed lines in the figure “Queued Service Invocation” on page 1‑2.The administrator must define at least one queue server group with TMS_QM as the transaction manager server for the group.
• The message queue server, TMQUEUE(5), is used to enqueue and dequeue messages. This provides a surrogate server for doing message operations for clients and servers, whether or not they are local to the queue.
• The message forwarding server, TMQFORWARD(5), is used to dequeue and forward messages to application servers. The Oracle Tuxedo system provides a main() for servers that handles server initialization and termination, allocates buffers to receive and dispatch incoming requests to service routines, and routes replies to the correct destination. All of this processing is transparent to the application. Existing servers do not dequeue their own messages or enqueue replies. One goal of Oracle Tuxedo /Q is to be able to use existing servers to service queued messages, without change. The TMQFORWARD server dequeues a message from one or more queues in the queue space, forwards the message to a server with a service that is named the same as the queue, waits for the reply, and queues the success reply or failure reply on the associated reply or failure queues, respectively, as specified by the originator of the message (if the originator specified a reply or failure queue).An administrator also must create a queue space using the queue administration program, qmadmin(1), or the APPQ_MIB(5) Management Information Base (MIB). The queue space contains a collection of queues. In the figure “Queued Service Invocation” on page 1‑2, for example, four queues are present within the APP queue space. There is a one-to-one mapping of queue space to queue server group since each queue space is a resource manager (RM) instance and only a single RM can exist in a group.
• A single message queue server, TMQUEUE in the figure “Queued Service Invocation” on page 1‑2, can be used to enqueue and dequeue messages for multiple queues within a single queue space.
• A single message forwarding server, TMQFORWARD in the figure “Queued Service Invocation” on page 1‑2, can be used to dequeue and forward messages to services from multiple queues within a single queue space.
• Two instances of the transaction manager server, TMS_QM in the figure “Queued Service Invocation” on page 1‑2, can be used to complete transactions for multiple queues within a single queue space. One instance of the transaction manager server is reserved for non-blocking transactions so that they will be processed as quickly as possible and not be held up by blocking transactions. Blocking transactions are handled by the second instance of the transaction manager server.The administrator can define a single server group in the application configuration for the queue space by specifying the group in UBBCONFIG or by using tmconfig(1) (see tmconfig, wtmconfig(1)) to add the group dynamically.Part of the task of defining a queue is specifying the order for messages on the queue. Queue ordering can be determined by message availability time, expiration time, priority, FIFO, LIFO, or a combination of these criteria.The administrator specifies one or more of these sort criteria for the queue, listing the most significant criteria first. The FIFO and LIFO values must be the least significant sort criteria. Messages are put on the queue according to the specified sort criteria and dequeued from the top of the queue. The administrator can configure as many message queuing servers as are needed to keep up with the requests generated by clients for the stable queues.For housekeeping purposes, the administrator can set up a command to be executed when a threshold is reached for a queue that does not routinely get drained. This can be based on the bytes, blocks, or percentage of the queue space used by the queue or the number of messages on the queue. The command might boot a TMQFORWARD server to drain the queue or send mail to the administrator for manual handling.You can also use the queued message facility for peer-to-peer communication between clients, such that a client communicates with other clients without using any forwarding server. The peer-to-peer communication model is shown in Figure 1‑2.Figure 1‑2 Peer-to-Peer CommunicationIn steps 1 through 3 of the figure “Queued Service Invocation” on page 1‑2, a client enqueues a message to the SERVICE1 queue in the APP queue space using tpenqueue(3c). Optionally, the name of a reply queue and a failure queue can be included in the call to tpenqueue(). In the example they are the queues CLIENT_REPLY1 and FAILURE_Q. The client can specify a correlation identifier value to accompany the message. This value is persistent across queues so that any reply or failure message associated with the queued message can be identified when it is read from the reply or failure queue.The client can use the default queue ordering (for example, a time after which the message should be made available for dequeuing), or can specify an override of the default queue ordering (asking, for example, that this message be put at the top of the queue or ahead of another message on the queue). tpenqueue() sends the message to the TMQUEUE server, the message is queued, and an acknowledgment (step 3) is sent to the client; the acknowledgment is not seen directly by the client but can be assumed when the client gets a successful return. (A failure return includes information about the nature of the failure.)A message identifier assigned by the queue manager is returned to the application. The identifier can be used to dequeue a specific message. It can also be used in another tpenqueue() to identify a message already on the queue that the subsequent message should be enqueued ahead of.When using Oracle Tuxedo /Q for queued service invocation, and the message reaches the top of the queue, the TMQFORWARD server dequeues the message and forwards it, via tpcall(3c), to a service with the same name as the queue name. In the figure “Queued Service Invocation” on page 1‑2, the queue and the service are named SERVICE1 and steps 4, 5, and 6 in the figure show this. The client identifier and the application authentication key are set to the client that caused the message to be enqueued; they accompany the dequeued message as it is sent to the service.When the service returns a reply, TMQFORWARD enqueues the reply (with an optional user-return code) to the reply queue (step 7 in the figure “Queued Service Invocation” on page 1‑2).Sometime later (steps 8, 9 and 10 in the figure “Queued Service Invocation” on page 1‑2), the client uses tpdequeue(3c) to read from the reply queue CLIENT_REPLY1 in order to get the reply message.You can dequeue messages without removing them from the queue by using the TPQPEEK flag with tpdequeue(). Messages that have expired or have been deleted by an administrator are immediately removed from the queue.A better approach is to enqueue the message within the caller's transaction, as is shown in Figure 1‑3.Figure 1‑3 Transaction DemarcationIn the figure, the client starts a transaction, queues the message and commits the transaction. The message is dequeued within a second transaction started by TMQFORWARD; the service is called with tpcall(3c), is executed and the reply is enqueued within the same transaction. A third transaction, started by the client, is used to dequeue the reply (and possibly enqueue another request message). In ongoing processing, the third and first transactions can meld into one since enqueuing the next request can be done in the same transaction as dequeuing the response from the previous request.A reply queue can be either specified or not by the application when calling tpenqueue(). The effect is as follows:
• In the case where the application explicitly dequeues the message using tpdequeue(), it is the responsibility of the application to call tpenqueue() to enqueue the reply. Normally, this would be done in the same transaction in which the request message is dequeued and executed so the entire operation is handled atomically (that is, the reply is enqueued only if the transaction succeeds).
• In the case where the message is automatically processed by a service (dequeued and passed to the application via a tpcall()) by TMQFORWARD, TMQFORWARD enqueues a reply if the application service returns successfully (that is, the service routine called tpreturn(3c) with TPSUCCESS and tpcall() did not return 1). If tpcall() receives data, then the typed buffer used is enqueued to the reply queue. If no data is received in tpcall(), then a message with no data (that is, a NULL message) is enqueued; the fact that a message is enqueued (even if NULL) is sufficient to signify that the operation has been completed.Other variations come about because the application may either dequeue messages directly or use the TMQFORWARD server and because an error may cause a transaction to be rolled back and the message requeued while logic dictates that the transaction should be committed. These variations and ways to deal with them are discussed in “Oracle Tuxedo /Q Administration” on page 2‑1, “Oracle Tuxedo /Q C Language Programming” on page 3‑1, and “Oracle Tuxedo /Q COBOL Language Programming” on page 4‑1.
• The application program and/or the administrator can control the ordering of messages on the queue. Control is via the sort criteria, which may be based on message availability time, expiration time, priority, LIFO, FIFO, or a combination of these criteria. The application can override the ordering to place the message at the queue top or ahead of a specific message that is already queued.