![]() |
![]() |
|
|
Enqueuing Messages
The syntax for tpenqueue() is as follows:
#include <atmi.h>
int tpenqueue(char *qspace, char *qname, TPQCTL *ctl,
char *data, long len, long flags)
When a tpenqueue() call is issued, it tells the system to store a message on the queue identified in qname in the space identified in qspace. The message is in the buffer pointed to by data and has a length of len. By the use of bit settings in flags, the system is informed how the call to tpenqueue() is to be handled. Further information about the handling of the enqueued message and replies is provided in the TMQCTL structure pointed to by ctl.
tpenqueue(3c) Arguments
There are some important arguments to control the operation of tpenqueue(3c). Let's look at some of them.
tpenqueue(): The qspace Argument
qspace identifies a queue space previously created by the administrator. When a server is defined in the SERVERS section of the configuration file, the service names it offers are aliases for the actual queue space name (which is specified as part of the OPENINFO parameter in the GROUPS section). For example, when your application uses the server TMQUEUE, the value pointed at by the qspace argument is the name of a service advertised by TMQUEUE. If no service aliases are defined, the default service is the same as the server name, TMQUEUE. In this case the configuration file might include:
TMQUEUE
SRVGRP = QUE1 SRVID = 1
GRACE = 0 RESTART = Y CONV = N
CLOPT = "-A"
or
CLOPT = "-s TMQUEUE"
The entry for server group QUE1 has an OPENINFO parameter that specifies the resource manager, the pathname of the device and the queue space name. The qspace argument in a client program then looks like this:
if (tpenqueue("TMQUEUE", "STRING", (TPQCTL *)&qctl,
(char *)reqstr, 0,0) == -1) {
Error checking
}
The example shown on the TMQUEUE(5) reference page shows how alias service names can be included when the server is built and specified in the configuration file. The sample program in A Sample Application, also specifies an alias service name.
tpenqueue(): The qname Argument
Within a queue space, when queues are being used to invoke services, message queues are named according to the application services available to process requests. qname is a pointer to such an application service. Otherwise, qname is simply the name of the location where the message is to be stored until it is dequeued by an application (either the same application that enqueued it or another one).
tpenqueue(): The data and len Arguments
data points to a buffer that contains the message to be processed. The buffer must be one that was allocated with a call to tpalloc(3c). len gives the length of the message. Some BEA Tuxedo buffer types (such as FML) do not require that the length of the message be specified; in such cases, the len argument is ignored. data can be NULL; when it is, len is ignored and the message is enqueued with no data portion.
tpenqueue(): The flags Arguments
flags values are used to tell the BEA Tuxedo system how the tpenqueue() call is handled; the following are valid flags:
TPQCTL Structure
The third argument to tpenqueue() is a pointer to a structure of type TPQCTL. The TPQCTL structure has members that are used by the application and by the BEA Tuxedo system to pass parameters in both directions between application programs and the queued message facility. The client that calls tpenqueue() sets flags to mark fields the application wants the system to fill in. The structure is also used by tpdequeue(); some of the fields do not come into play until the application calls that function. The complete structure is shown in the following listing.
The tpqctl_t Structure
#define TMQNAMELEN 15
#define TMMSGIDLEN 32
#define TMCORRIDLEN 32
struct tpqctl_t { /* control parameters to queue primitives */
long flags; /* indicates which of the values are set */
long deq_time; /* absolute/relative time for dequeuing */
long priority; /* enqueue priority */
long diagnostic; /* indicates reason for failure */
char msgid[TMMSGIDLEN]; /* ID of message before which to queue */
char corrid[TMCORRIDLEN]; /* correlation ID used to identify message */
char replyqueue[TMQNAMELEN+1]; /* queue name for reply message */
char failurequeue[TMQNAMELEN+1]; /* queue name for failure message */
CLIENTID cltid; /* client identifier for originating client */
long urcode; /* application user-return code */
long appkey; /* application authentication client key */
long delivery_qos; /* delivery quality of service */
long reply_qos; /* reply message quality of service */
long exp_time; /* expiration time */
};
typedef struct tpqctl_t TPQCTL;
The following is a list of valid bits for the flags parameter controlling input information for tpenqueue().
Additionally, the urcode field of TPQCTL can be set with a user-return code. This value will be returned to the application that calls tpdequeue(3c) to dequeue the message.
On output from tpenqueue(), the following fields may be set in the TPQCTL structure:
long flags; /* indicates which of the values are set */
char msgid[32]; /* ID of enqueued message */
long diagnostic; /* indicates reason for failure */
The following is a valid bit for the flags parameter controlling output information from tpenqueue(). If this flag is turned on when tpenqueue() is called, the /Q server TMQUEUE(5) populates the associated element in the structure with a message identifier. If this flag is turned off when tpenqueue() is called, TMQUEUE() does not populate the associated element in the structure with a message identifier.
The remaining members of the control structure are not used on input to tpenqueue().
If the call to tpenqueue() fails and tperrno(5) is set to TPEDIAGNOSTIC, a value indicating the reason for failure is returned in ctl->diagnostic. The possible values are:
Overriding the Queue Order
If the administrator, in creating a queue, allows tpenqueue() calls to override the order of messages on the queue, you have two mutually exclusive ways to use that capability. You can specify that the message is to be placed at the top of the queue by setting flags to include TPQTOP or you can specify that it be placed ahead of a specific message by setting flags to include TPQBEFOREMSGID and setting ctl->msgid to the ID of the message you wish to precede. This assumes that you saved the message-ID from a previous call in order to be able to use it here. Your administrator must tell you what the queue supports; it can be created to allow either or both of these overrides, or to allow neither.
Overriding the Queue Priority
You can set a value in ctl->priority to specify the priority of the message. The value must be in the range 1 to 100; the higher the number the higher the priority. If priority was not one of the queue ordering parameters, setting a priority here has no effect on the dequeuing order, however the priority value is retained so that the value can be inspected when the message is dequeued.
Setting a Message Availability Time
You can specify in deq_time either an absolute time or a time relative to the completion of the enqueuing operation for the message to be made available. You set flags to include either TPQTIME_ABS or TPQTIME_REL to indicate how the value should be treated. A queue may be created with time as a queue ordering criterion, in which case the messages are ordered by the message availability time.
BEA Tuxedo /Q provides a function, gp_mktime(3c), that is used to convert a date and time provided in a tm structure to the number of seconds since January 1, 1970. The time(2) and mktime(3C) functions may also be used instead of gp_mktime(3c). The value is returned in time_t, a typedef'd long. To set an absolute time for the message to be dequeued (we are using 12:00 noon, December 9, 2001), do the following.
#include <stdio.h>
#include <time.h>
static char *const wday[] = {
"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday", "-unknown-"
};
struct tm time_str;
/*...*/
time_str.tm_year = 2001 - 1900;
time_str.tm_mon = 12 - 1;
time_str.tm_mday = 9;
time_str.tm_hour = 12;
time_str.tm_min = 0;
time_str.tm_sec = 1;
time_str.tm_isdst = -1;
#include <atmi.h>
TPQCTL qctl;
if ((qctl->deq_time = (long)gp_mktime(&time_str)) == -1) {
/* check for errors */
}
qctl->flags = TPQTIME_ABS
if (tpenqueue(qspace, qname, qctl, *data,*len,*flags) == -1) {
/* check for errors */
}
If you want to specify a relative time for dequeuing, for example, nnn seconds after the completion of the enqueuing operation, place the number of seconds in deq_time and set flags to include TPQTIME_REL.
tpenqueue() and Transactions
If a caller of tpenqueue() is in transaction mode and TPNOTRAN is not set, then the enqueuing is done within the caller's transaction. The caller knows for certain from the success or failure of tpenqueue() whether the message was enqueued or not. If the call succeeds, the message is guaranteed to be on the queue. If the call fails, the transaction is rolled back, including the part where the message was placed on the queue.
If a caller of tpenqueue() is not in transaction mode or if TPNOTRAN is set, the message is enqueued outside of the caller's transaction. If the call to tpenqueue() returns success, the message is guaranteed to be on the queue. If the call to tpenqueue() fails with a communication error or with a timeout, the caller is left in doubt about whether the failure occurred before or after the message was enqueued.
Note that specifying TPNOTRAN while the caller is not in transaction mode has no meaning.
![]() |
![]() |
![]() |
|
Copyright © 2001 BEA Systems, Inc. All rights reserved.
|