BEA Logo BEA Tuxedo Release 7.1

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

 

   Tuxedo Doc Home   |   Programming   |   Topic List   |   Previous   |   Next   |   Contents

   Using the BEA Tuxedo System /Q Component

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:

TPNOTRAN

If the caller is in transaction mode and this flag is set, the message is not queued within the caller's transaction. A caller in transaction mode that sets this flag is still subject to the transaction timeout (and no other) when queuing the message. If message queuing fails, the caller's transaction is not affected.

TPNOBLOCK

The message is not enqueued if a blocking condition exists. If this flag is set and a blocking condition exists such as the internal buffers into which the message is transferred are full, the call fails and tperrno(5) is set to TPEBLOCK. If this flag is set and a blocking condition exists because the target queue is opened exclusively by another application, the call fails, tperrno() is set to TPEDIAGNOSTIC, and the diagnostic field of the TPQCTL structure is set to QMESHARE. In the latter case, the other application, which is based on a BEA product other than the BEA Tuxedo system, opened the queue for exclusive read and/or write using the Queuing Services API (QSAPI).

When TPNOBLOCK is not set and a blocking condition exists, the caller blocks until the condition subsides or a timeout occurs (either transaction or blocking timeout). If a timeout occurs, the call fails and tperrno() is set to TPETIME.

TPNOTIME

Setting this flag signifies that the caller is willing to block indefinitely and wants to be immune to blocking timeouts. Transaction timeouts may still occur.

TPSIGRSTRT

Setting this flag indicates that any underlying system calls that are interrupted by a signal should be reissued. When this flag is not set and a signal interrupts a system call, the call fails and sets tperrno(5) to TPGOTSIG.

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().

TPNOFLAGS

No flags or values are set. No information is taken from the control structure. Leaving fields of the structure not set is equivalent to a setting of TPNOFLAGS.

TPQTOP

Setting this flag indicates that the queue ordering be overridden and the message placed at the top of the queue. This request may not be granted depending on whether or not the queue was configured to allow overriding the queue ordering to put a message at the top of the queue. TPQTOP and TPQBEFOREMSGID are mutually exclusive flags

TPQBEFOREMSGID

Setting this flag indicates that the queue ordering be overridden and the message placed in the queue before the message identified by ctl->msgid. This request may not be granted depending on whether or not the queue was configured to allow overriding the queue ordering. TPQTOP and TPQBEFOREMSGID are mutually exclusive flags. Note that the entire 32 bytes of the message identifier value are significant, so the value identified by ctl->msgid must be completely initialized (for example, padded with null characters).

TPQTIME_ABS

If this flag is set, the message is made available after the time specified by ctl->deq_time. The deq_time is an absolute time value as generated by time(2) or mktime(3C), if they are available to your application, or gp_mktime(3c), provided with the BEA Tuxedo system. The value set in ctl->deq_time is the number of seconds since 00:00:00 Universal Coordinated Time-UTC, January 1,1970. The absolute time is set based on the clock on the machine where the queue manager process resides. TPQTIME_ABS and TPQTIME_REL are mutually exclusive flags.

TPQTIME_REL

If this flag is set, the message is made available after a time relative to the completion of the enqueuing operation. ctl->deq_time specifies the number of seconds to delay after the enqueuing completes before the submitted message should be available. TPQTIME_ABS and TPQTIME_REL are mutually exclusive flags.

TPQPRIORITY

If this flag is set, the priority at which the request should be enqueued is stored in ctl->priority. The priority must be in the range 1 to 100, inclusive. The higher the number, the higher the priority, that is, a message with a higher number is dequeued before a message with a lower number from queues ordered by priority. For queues not ordered by priority, the value is informational.

If this flag is not set, the priority for the message is 50 by default.

TPQCORRID

If this flag is set, the correlation identifier value specified in ctl->corrid is available when a request is dequeued with tpdequeue(3c). This identifier accompanies any reply or failure message that is queued so an application can correlate a reply with a particular request. Note that the entire 32 bytes of the correlation identifier value are significant, so the value specified in ctl->corrid must be completely initialized (for example, padded with null characters).

TPQREPLYQ

If this flag is set, a reply queue named in ctl->replyqueue is associated with the queued message. Any reply to the message is queued to the named queue within the same queue space as the request message. This string must be NULL-terminated (maximum 15 characters in length). If a reply is generated for the service and a reply queue is not specified or the reply queue does not exist, the reply is dropped.

TPQFAILUREQ

If this flag is set, a failure queue named in the ctl->failurequeue is associated with the queued message. If (1) the enqueued message is processed by TMQFORWARD(), (2) TMQFORWARD was started with the -d option, and (3) the service fails and returns a non-null reply, a failure message consisting of the reply and its associated tpurcode is enqueued to the named queue within the same queue space as the original request message. This string must be NULL-terminated (maximum 15 characters in length).

TPQDELIVERYQOS, TPQREPLYQOS

If the TPQDELIVERYQOS flag is set, the flags specified by ctl->delivery_qos control the quality of service for delivery of the message. In this case, one of three mutually exclusive flags- TPQQOSDEFAULTPERSIST, TPQQOSPERSISTENT, or TPQQOSNONPERSISTENT-must be set in ctl->delivery_qos. If TPQDELIVERYQOS is not set, the default delivery policy of the target queue dictates the delivery quality of service for the message.

If the TPQREPLYQOS flag is set, the flags specified by ctl->reply_qos control the quality of service for any reply to the message. In this case, one of three mutually exclusive flags-TPQQOSDEFAULTPERSIST, TPQQOSPERSISTENT, or TPQQOSNONPERSISTENT-must be set in ctl->reply_qos. The TPQREPLYQOS flag is used when a reply is returned from messages processed by TMQFORWARD. Applications not using TMQFORWARD to invoke services may use the TPQREPLYQOS flag as a hint for their own reply mechanism.

If TPQREPLYQOS is not set, the default delivery policy of the ctl->replyqueue queue dictates the delivery quality of service for any reply. Note that the default delivery policy is determined when the reply to a message is enqueued. That is, if the default delivery policy of the reply queue is modified between the time that the original message is enqueued and the reply to the message is enqueued, the policy used is the one in effect when the reply is finally enqueued.

The following is the list of valid flags for ctl->delivery_qos and ctl->reply_qos:

TPQQOSDEFAULTPERSIST

This flag specifies that the message is to be delivered using the default delivery policy specified on the target queue.

TPQQOSPERSISTENT

This flag specifies that the message is to be delivered in a persistent manner using the disk-based delivery method. When specified, this flag overrides the default delivery policy specified on the target queue.

TPQQOSNONPERSISTENT

This flag specifies that the message is to be delivered in a non-persistent manner using the memory-based delivery method. Specifically, the message is queued in memory until it is dequeued. When specified, this flag overrides the default delivery policy specified on the target queue. If the caller is transactional, non-persistent messages are enqueued within the caller's transaction, however, non-persistent messages are lost if the system is shut down, crashes, or the IPC shared memory for the queue space is removed.

TPQEXPTIME_ABS

If this flag is set, the message has an absolute expiration time, which is the absolute time when the message will be removed from the queue.

The absolute expiration time is determined by the clock on the machine where the queue manager process resides.

The absolute expiration time is indicated by the value stored in ctl->exp_time. The value of ctl->exp_time must be set to an absolute time value generated by time(2), mktime(3C), or gp_mktime(3c) (the number of seconds since 00:00:00 Universal Coordinated Time-UTC, January 1, 1970).

If an absolute time is specified that is earlier than the time of the enqueue operation, the operation succeeds, but the message is not counted for the purpose of calculating thresholds. If the expiration time is before the message availability time, the message is not available for dequeuing unless either the availability or expiration time is changed so that the availability time is before the expiration time. In addition, these messages are removed from the queue at expiration time even if they were never available for dequeuing. If a message expires while it is within a transaction, the expiration does not cause the transaction to fail. Messages that expire while being enqueued or dequeued within a transaction are removed from the queue when the transaction ends. There is no notification that the message has expired.

TPQEXPTIME_ABS, TPQEXPTIME_REL, and TPQEXPTIME_NONE are mutually exclusive flags. If none of these flags is set, the default expiration time associated with the target queue is applied to the message.

TPQEXPTIME_REL

If this flag is set, the message has a relative expiration time, which is the number of seconds after the message arrives at the queue that the message is removed from the queue. The relative expiration time is indicated by the value stored in ctl->exp_time.

If the expiration time is before the message availability time, the message is not available for dequeuing unless either the availability or expiration time is changed so that the availability time is before the expiration time. In addition, these messages are removed from the queue at expiration time even if they were never available for dequeuing. The expiration of a message during a transaction, does not cause the transaction to fail. Messages that expire while being enqueued or dequeued within a transaction are removed from the queue when the transaction ends. There is no acknowledgment that the message has expired.

TPQEXPTIME_ABS, TPQEXPTIME_REL, and TPQEXPTIME_NONE are mutually exclusive flags. If none of these flags is set, the default expiration time associated with the target queue is applied to the message.

TPQEXPTIME_NONE

Setting this flag indicates that the message should not expire, even if the default policy of the queue includes an expiration time.

TPQEXPTIME_ABS, TPQEXPTIME_REL, and TPQEXPTIME_NONE are mutually exclusive flags. If none of these flags is set, the default expiration time associated with the target queue is applied to the message.

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.

TPQMSGID

If this flag is set and the call to tpenqueue() is successful, the message identifier is stored in ctl->msgid. The entire 32 bytes of the message identifier value are significant, so the value stored in ctl->msgid is completely initialized (for example, padded with null characters). The actual padding character used for initialization varies between releases of the BEA Tuxedo /Q component.

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:

[QMEINVAL]

An invalid flag value was specified.

[QMEBADRMID]

An invalid resource manager identifier was specified.

[QMENOTOPEN]

The resource manager is not currently open.

[QMETRAN]

The call was made in transaction mode or was made with the TPNOTRAN flag set and an error occurred trying to start a transaction in which to enqueue the message. This diagnostic is not returned by queue managers from BEA Tuxedo Release 7.1 or later.

[QMEBADMSGID]

An invalid message identifier was specified.

[QMESYSTEM]

A system error occurred. The exact nature of the error is written to a log file.

[QMEOS]

An operating system error occurred.

[QMEABORTED]

The operation was aborted. If the aborted operation was being executed within a global transaction, the global transaction is marked rollback-only. Otherwise, the queue manager aborts the operation.

[QMEPROTO]

An enqueue was done when the transaction state was not active.

[QMEBADQUEUE]

An invalid or deleted queue name was specified.

[QMENOSPACE]

Due to an insufficient resource, such as no space on the queue, the message with its required quality of service (persistent or non-persistent storage) was not enqueued. QMENOSPACE is returned when any of the following configured resources is exceeded: (1) the amount of disk (persistent) space allotted to the queue space, (2) the amount of memory (non-persistent) space allotted to the queue space, (3) the maximum number of simultaneously active transactions allowed for the queue space, (4) the maximum number of messages that the queue space can contain at any one time, (5) the maximum number of concurrent actions that the Queuing Services component can handle, or (6) the maximum number of authenticated users that may concurrently use the Queuing Services component.

[QMERELEASE]

An attempt was made to enqueue a message to a queue manager that is from a version of the BEA Tuxedo system that does not support a newer feature.

[QMESHARE]

When enqueuing a message from a specified queue, the specified queue is opened exclusively by another application. The other application is one based on a BEA product other than the BEA Tuxedo system that opened the queue for exclusive read and/or write using the Queuing Services API (QSAPI).

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.

  1. Place the values for the date you want to use in the tm structure.

    #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;

  2. Call gp_mktime to produce a value for deq_time and set the flags to indicate that an absolute time is being provided.

    #include <atmi.h>
    TPQCTL qctl;
    if ((qctl->deq_time = (long)gp_mktime(&time_str)) == -1) {
    /* check for errors */
    }
    qctl->flags = TPQTIME_ABS

  3. Call tpenqueue().

    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.