Thursday, November 1, 2012

Loadrunner Asynchronous Results Polling Using 11.5 Web Async


Some user action trigger asynchronous server-side operations.  The user can then be forced to check for results periodically by polling the server.  Loadrunner 11.5 provides asynchronous logic allowing callback functions to be specified which are called when the async call finally returns.  The following example gives one example of using the asynchronous callbacks as follows:

  • Include web_api.h to load some needed symbols
  • To capture the time it takes for the async response to come back, specify a global variable showing done state
  • Before the async call, set async polling properties using web_reg_async_attributes such as how often to poll, which callback functions to use, etc.
  • Define the callback functions to be called when the async response is returned and update the done state variable in the callback
  • Make the async call
  • To get the response time, wait until the callback has updated the global state variable
  • End the transaction
  • Stop the async polling

The following shows an example of a script doing this, and the next section shows the script's vugen console output.

Script

// Specify include files
#ifndef _GLOBALS_H
#define _GLOBALS_H

#include "web_api.h"
#endif // _GLOBALS_H
// End include files

// Define a global variable holding done state
int done;

Action()
{
    web_url("wiki",
        "URL=http://ajaxify.com/run/wiki",
        "Resource=0",
        "RecContentType=text/html",
        "Referer=",
        "Snapshot=t37.inf",
        "Mode=HTML",
        LAST);

    // Initialize the global done state variable, and start the async transaction variable
    done = 0;
    lr_start_transaction("async-call");

   // Define the request to be handled asynchronously, in this case a "?messages" call
   // Specify the polling interval of 5 seconds
   // Specify the callback functions that will be called when the response is returned.
   // The callback functions are defined below.     web_reg_async_attributes("ID=Poll_0",
        "URL=http://ajaxify.com/run/wiki/content.php?messages",
        "Pattern=Poll",
        "PollIntervalMs=5000",
        "RequestCB=Poll_0_RequestCB",
        "ResponseBodyBufferCB=Poll_0_ResponseBodyBufferCB",
        "ResponseCB=Poll_0_ResponseCB",
        LAST);

    // now make the async call.
    // note that the script will not block on this call.  processing will continue on past this step while the request is handles asynchronously
    web_url("content.php",
        "URL=http://ajaxify.com/run/wiki/content.php?messages",
        "Resource=0",
        "RecContentType=text/xml",
        "Referer=http://{host_ajaxify_com}/run/wiki/",
        "Snapshot=t38.inf",
        "Mode=HTML",
        LAST);


    // To capture the response time of the async call, wait until the callback is called.
    // Without this, the script would move past and complete the iteration before the callback is called.     while (done==0)
    {
        lr_think_time(1);
    }

    // once the callback has been called, end the transaction to get the response time.
     lr_end_transaction("async-call"LR_AUTO);
     
   // stop the polling
   web_stop_async("ID=Poll_0",
        LAST);

    return 0;
}



/*
*    Callback Implementation
*
*
*/

int Poll_0_RequestCB()
{
    //enter your implementation for RequestCB() here

    return WEB_ASYNC_CB_RC_OK;
}

int Poll_0_ResponseBodyBufferCB(
    const char *    aLastBufferStr,
    int                aLastBufferLen,
    const char *    aAccumulatedStr,
    int                aHttpStatusCode)
{
    //enter your implementation for ResponseBodyBufferCB() here

    // when the response is received, update the global variable
    done = 1;
    // print out the response body and length
    lr_message("in Poll_0_ResponseBodyBufferCB response body callback");
    lr_message("in Poll_0_ResponseBodyBufferCB response body callback, lastBufferLen=%d", aLastBufferLen);
 
    return WEB_ASYNC_CB_RC_OK;
}

int Poll_0_ResponseCB(
    const char *    aResponseHeadersStr,
    int                aResponseHeadersLen,
    const char *    aResponseBodyStr,
    int                aResponseBodyLen,
    int                aHttpStatusCode)
{
    //enter your implementation for ResponseCB() here
 
    lr_message("in Poll_0_ResponseCB response callback, headerLen=%d, bodyLen=%d", aResponseHeadersLen, aResponseBodyLen);
    lr_message("in Poll_0_ResponseCB response callback, header=%s", aResponseHeadersStr);
    lr_message("in Poll_0_ResponseCB response callback, body=%s", aResponseBodyStr);
 
    return WEB_ASYNC_CB_RC_OK;
}


Console Output

Running Vuser...
Starting iteration 1.
Notify: max connections per server : 6
Starting action Action.
Action.c(16): web_url("wiki") started      [MsgId: MMSG-26355]
Action.c(16): Redirecting "http://ajaxify.com/run/wiki" (redirection depth is 0)       [MsgId: MMSG-26694]
Action.c(16): To location "http://ajaxify.com/run/wiki/"  [MsgId: MMSG-26693]
Action.c(16): Found resource "http://ajaxify.com/run/Lib/css/demo.css" in HTML "http://ajaxify.com/run/wiki/"       [MsgId: MMSG-26659]
Action.c(16): Found resource "http://ajaxify.com/run/wiki/wiki.css" in HTML "http://ajaxify.com/run/wiki/"       [MsgId: MMSG-26659]
Action.c(16): Found resource "http://ajaxify.com/run/Lib/js/util.js" in HTML "http://ajaxify.com/run/wiki/"       [MsgId: MMSG-26659]
Action.c(16): Found resource "http://ajaxify.com/run/Lib/js/ajaxCaller.js" in HTML "http://ajaxify.com/run/wiki/"       [MsgId: MMSG-26659]
Action.c(16): Found resource "http://ajaxify.com/run/wiki/wiki.js" in HTML "http://ajaxify.com/run/wiki/"       [MsgId: MMSG-26659]
Action.c(16): Found resource "http://ajaxify.com/favicon.ico" in HTML "http://ajaxify.com/run/wiki/"       [MsgId: MMSG-26659]
Action.c(16): Found resource "http://ajaxify.com/run/Lib/php/button.php" in HTML "http://ajaxify.com/run/wiki/"       [MsgId: MMSG-26659]
Action.c(16): web_url("wiki") was successful, 22491 body bytes, 2152 header bytes, 24 chunking overhead bytes      [MsgId: MMSG-26385]
Action.c(26): Notify: Transaction "polling" started.
Action.c(41): web_reg_async_attributes started       [MsgId: MMSG-26355]
Action.c(41): web_reg_async_attributes was successful      [MsgId: MMSG-26392]
Action.c(50): web_url("content.php") started    [MsgId: MMSG-26355]
Action.c(50): "ID=poll_0" && "Pattern=Poll" && "PollIntervalMs=5000" now applied to URL="http://ajaxify.com/run/wiki/content.php?messages" (RelFrameId=1, Internal ID=10)     [MsgId: MMSG-35172]
Action.c(50): Retaining cross-step download of URL="http://ajaxify.com/run/wiki/content.php?messages" (RelFrameId=1, Internal ID=10)     [MsgId: MMSG-27658]
Action.c(50): web_url("content.php") was successful, 0 body bytes, 0 header bytes       [MsgId: MMSG-26386]
Action.c(62): lr_think_time: 1.00 seconds.
in Poll_0_ResponseBodyBufferCB response body callback
in Poll_0_ResponseBodyBufferCB response body callback, lastBufferLen=928
in Poll_0_ResponseBodyBufferCB response body callback
in Poll_0_ResponseBodyBufferCB response body callback, lastBufferLen=0
in Poll_0_ResponseCB response callback, headerLen=319, bodyLen=928
in Poll_0_ResponseCB response callback, header=HTTP/1.1 200 OK
Server: nginx/0.8.53
Date: Thu, 01 Nov 2012 21:18:42 GMT
Content-Type: text/xml
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/5.3.5-1ubuntu7.11
Expires: 0
Last-Modified: Thu, 01 Nov 2012 21:18:42 GMT
cache-control: no-store, no-cache, must-revalidate
Pragma: no-cache


in Poll_0_ResponseCB response callback, body=<messages>  <message>
      <id>10</id>
      <lastAuthor>lastAuthor</lastAuthor>
      <ranking>100</ranking>
      <content>Wonder%20Wonder%20ffff%0AStuff%20here%20for%20123fdsfd%0Atest%0Avbnvytytry%0Aokadfasdf%0Artyry%0Artyryry%0Arytry%0Adfgvdfg%0A%0Asdfsad%0A%0Asdfsd%0A%0Aghghhgggh%0A%0Atesteste%0A%0AZe%20woiauha%0A%20df%0A%0Axcvx%0AHello%20friends%21%0Ahello%20folks%0Ahi%0Ajiadsasd%0A%0A%0Azzz</content>
  </message>  <message>
      <id>2</id>
      <lastAuthor>lastAuthor</lastAuthor>
      <ranking>200</ranking>
      <content>ABC%0Aklljljl%0Ak%3Bk%3B%3Bk%3B%0Aggugj%0A%0Affff%0A%0Aasdf%0A%0Abla%0Aqwe%0Aqweqwe%0Ajnknknkjkvfgh%0A</content>
  </message>  <message>
      <id>3</id>
      <lastAuthor>lastAuthor</lastAuthor>
      <ranking>300</ranking>
      <content>This%20is%20line%201%0AThis%20is%20line%202.%0AEnd%0A.%0Adffdfg123123123%0Aawgaw%0Afsdf%0Atestes%0Aasdfadf%0Aadsasd</content>
  </message></messages>
Action.c(62): Issuing a "POLL" request for conversation with ID="poll_0" and "PollIntervalMs=5000". Scheduling due at t=13494, URL="http://ajaxify.com/run/wiki/content.php?messages"     [MsgId: MMSG-35169]
Action.c(62): "ID=poll_0" && "Pattern=Poll" && "PollIntervalMs=5000" now applied to URL="http://ajaxify.com/run/wiki/content.php?messages" (RelFrameId=, Internal ID=11)     [MsgId: MMSG-35172]
Action.c(67): Notify: Transaction "polling" ended with "Pass" status (Duration: 4.0431 Think Time: 1.8491 Wasted Time: 0.0121).
Action.c(69): web_stop_async started       [MsgId: MMSG-26355]
Action.c(69): Notify: Deleting Conversation Information with ID="poll_0"
Action.c(69): Aborting download of URL "http://ajaxify.com/run/wiki/content.php?messages" (RelFrameId=, Internal ID=11) of conversation with ID="poll_0"  [MsgId: MMSG-35167]
in Poll_0_ResponseBodyBufferCB response body callback
in Poll_0_ResponseBodyBufferCB response body callback, lastBufferLen=0
in Poll_0_ResponseCB response callback, headerLen=0, bodyLen=0
in Poll_0_ResponseCB response callback, header=
in Poll_0_ResponseCB response callback, body=
Action.c(69): web_stop_async was successful     [MsgId: MMSG-26392]
Ending action Action.
Ending iteration 1.
Ending Vuser...
Starting action vuser_end.
Ending action vuser_end.
Vuser Terminated.

No comments:

Post a Comment