![]() |
![]() |
|
|
Sending Asynchronous Messages
This section explains how to:
The type of asynchronous processing discussed in this section is sometimes referred to as fan-out parallelism because it allows a client's requests to be distributed (or "fanned out") simultaneously to several services for processing.
The other type of asynchronous processing supported by the BEA Tuxedo system is pipeline parallelism in which the tpforward() function is used to pass (or forward) a process from one service to another. For a description of the tpforward() function, refer to Writing Servers.
Sending an Asynchronous Request
The tpacall(3c) function sends a request to a service and immediately returns. Use the following signature to call the tpacall() function:
int
tpacall(char *svc, char *data, long len, long flags)
The following table describes the arguments to the tpacall() function.
tpacall( ) Function Arguments
The tpacall() function sends a request message to the service named in the svc parameter and immediately returns from the call. Upon successful completion of the call, the tpacall() function returns an integer that serves as a descriptor used to access the correct reply for the relevant request. While tpacall() is in transaction mode (as described in Writing Global Transactions) there may not be any outstanding replies when the transaction commits; that is, within a given transaction, for each request for which a reply is expected, a corresponding reply must eventually be received. If the value TPNOREPLY is assigned to the flags parameter, the parameter signals to tpacall() that a reply is not expected. When this flag is set, on success tpacall() returns a value of 0 as the reply descriptor. If subsequently passed to the tpgetrply() function, this value becomes invalid. Guidelines for using this flag value correctly when a process is in transaction mode are discussed in Writing Global Transactions. On error, tpacall() returns -1 and sets tperrno(5) to a value that reflects the nature of the error. tpacall() returns many of the same error codes as tpcall(). The differences between the error codes for these functions are based on the fact that one call is synchronous and the other, asynchronous. These errors are discussed at length in Managing Errors. Example: Sending an Asynchronous Message with TPNOTRAN | TPNOREPLY The following example shows how tpacall() uses the TPNOTRAN and TPNOREPLY flags. This code is similar to the code in Example: Sending a Synchronous Message with TPNOTRAN Set. In this case, however, a reply is not expected from the PRINTER service. By setting both TPNOTRAN and TPNOREPLY flags, the client is indicating that no reply is expected and the PRINTER service will not participate in the current transaction. This situation is discussed more fully in Managing Errors. Sending an Asynchronous Message with TPNOREPLY | TPNOTRAN Example: Sending Asynchronous Requests The following example shows a series of asynchronous calls that make up the total bank balance query. Because the banking application data is distributed among several database sites, an SQL query needs to be executed against each one. The application performs these queries by selecting one branch identifier per database site, and calling the ABAL or TBAL service for each site. The branch identifier is not used in the actual SQL query, but it enables the BEA Tuxedo system to route each request to the proper site. In the following code, the for loop invokes tpacall() once for each site. Sending Asynchronous Requests Getting an Asynchronous Reply A reply to a service call can be received asynchronously by calling the tpgetrply(3c) function. The tpgetrply() function dequeues a reply to a request previously sent by tpacall(). Use the following signature to call the tpgetrply() function: The following table describes the arguments to the tpgetrply() function. tpgetrply( ) Function Arguments
#include <stdio.h>
#include "atmi.h"
main()
{
char *rbuf; /* report buffer */
long rlen, rrlen; /* buffer lengths of send, reply buffers for report */
join application
if (rbuf = tpalloc("STRING", NULL, 0) == NULL) /* allocate space for report */
error
(void)strcpy(rbuf, "REPORT=accrcv DBNAME=accounts");/* send parms of report */
rlen = strlen(rbuf)+1; /* length of request */
start transaction
if (tpcall("REPORT", rbuf, rlen, &rbuf, &rrlen, 0)
== -1) /* get report print stream */ error
if (tpacall("PRINTER", rbuf, rrlen, TPNOTRAN|TPNOREPLY)
== -1) /* send report to printer */
error
. . .
commit transaction
free buffer
leave application
}audv->balance = 0.0;
(void)strcpy(audv->ermsg, "");
for (i=0; i<NSITE; i++) {
/* Prepare aud structure */
audv->b_id = sitelist[i]; /* routing done on this field */
/* Do tpacall */
if ((cd[i]=tpacall(sname, (char *)audv, sizeof(struct aud), 0))
== -1) {
(void)fprintf (stderr,
"%s: %s service request failed for site rep %ld\n",
pgmname, sname, sitelist[i]);
tpfree((char *)audv);
return(-1);
}
}int
tpgetrply(int *cd, char **data, long *len, long flags)
By default, the function waits for the arrival of the reply that corresponds to the value referenced by the cd parameter. During this waiting interval, a blocking timeout may occur. A time-out occurs when tpgetrply() fails and tperrno(5) is set to TPETIME (unless the flags parameter is set to TPNOTIME).
![]() |
![]() |
![]() |
|
Copyright © 2001 BEA Systems, Inc. All rights reserved.
|