next up previous contents
Next: Other sample programs Up: Tutorials Previous: Usage

Asynchronous RPC

Sometimes, we want an RPC to return immediately, and let the server return the results to the client asynchronously. For example, if it takes the quote server a long time to query a database to get the data, for reasons such as the large number of requests, we should let the client to continue to do other things and get the result later when it is ready.

With powerRPC this can be achieved easily. By setting the NON_BLOCKING property to true, an RPC call would return before the server function gets called. To receive the result later, the client can register a collection service, which is an RPC interface. When the server get the result, it calls upon this RPC registered by the clientgif to send the result back.

In this example, we demonstrate how to make our quote RPC asynchronous. We have two RPC interfaces defined in back.idl and over.idl. The client main function looks like this,

#include "over.h"
#include "back.h"
#include <signal.h>
#include <rpc/pmap_clnt.h>

main(int argc, char **argv)
{
    char            myhost[1024];
    if (argc < 3) {
        printf("usage: %s hostname ticker\n", argv[0]);
        exit(1);
    }
    pw_serv_init();

    back_1_unmap(0, 0);


    if (!back_1_reg(RPC_ANYSOCK, BACK, BACK_1, IPPROTO_TCP)) {
        printf("fail registering \n");
        exit(0);
    }
    pw_serv_async_enable();

    if (!over_bind(argv[1], 0, 0, 0)) {
        printf("fail connect to OVER server.\n");
        exit(0);
    }
    gethostname(myhost, 1023);
    getQuote(myhost, argv[2]);
    printf("Returned from 1st getQuote... now do something else ..\n");
    getQuote(myhost, argv[2]);
    printf("Returned from 2st getQuote... now do something else ..\n");
    getQuote(myhost, argv[2]);
    printf("Returned from 3rd getQuote... now do something else ..\n");

    while (1) {
        printf("happily doing ....\n");
        sleep(10);
    }
}

In the above, the client set up an asynchronous RPC back. Then it makes two calls of getQuote(), both return immediately. This getQuote() call is different from the one we studied earlier: it has an additional argument myhost. When the server receives the call, it gets the quote, and calls back myhost to send the results. The client enters a while loop, pretending to do other work, when the server's callback arrives, the client will be interrupted, and the returnQuote() implementation is called. The asynchronous behavior of the client's RPC is enabled by the pw_serv_async_enable() powerRPC library call {gif.

Below is the server's code.

#include "back.h"
#include <stdlib.h> 
/*
This is an asynchronous call, the client sends over its hostname,
after receiving the request, the server replies back to the client
immediately.  Then client and server reverse their roles, the 
server make the RPC returnQuote() to send the result to the client,
who is supposed to acting as a BACK server waiting for the result.
*/

void   getQuote(char *caller_host, char Ticker[8])
{

    stkQuote        quote;

    printf("Called by %s\n", caller_host);
    printf("sleep for a while ....\n");

    sleep(6);

    if (!back_bind(caller_host, 0, 0, 0)) {
        printf("client is not there!\n");
        return;
    }
    strcpy(quote.Ticker, Ticker);

    /* find the quotes */
    quote.Low = rand() % 100;
    quote.High = rand() % 100;
    quote.Close = rand() % 100;
    printf("now sending back quote ....\n");
    printf("%s %f %f %f\n", quote.Ticker,
           quote.Low, quote.High, quote.Close);

    returnQuote(&quote);

    back_unbind(0);
}



Copyright (C) Netbula LLC, 1996