XMLSERVICEASYNC

Async calls with PHP.

(*) Curl example “as is” … http://gonzalo123.com/2010/10/11/speed-up-php-scripts-with-asynchronous-database-queries
curl application example below, basically idea of ‘async’ can be thought of as curl REST requests acting like multiple browsers. Wherein, curl_multi_xxx functions issue many browser GET’ requests (sample). Therefore, curl_multi architecture is plain old HTTP requests, bunch-o-them, ‘remembered’ via handle, then simply wait on port response(es), collect $out=curl_multi_getcontent(handle);

DB2 behind REST fork.php

Now we understand curl_multi architecture is plain old HTTP requests, therefore, fork.php async PDO example works just fine (or ibm_db2, etc.).
fork.php
<?php
 $dbh = new PDO('ibm:*LOCAL', 'xxx','xxx');
 $t = filter_input(INPUT_GET, 't', FILTER_SANITIZE_STRING);
 if (!$t) $t = 1;
 $stmt = $dbh->prepare("select * from xmlservtst.animal where ID=?");
 $stmt->execute(array($t));
 $data = $stmt->fetchAll();
 echo json_encode($data);
?>


index.php
<?php
// index.php
class Fork
{
 private $_handles = array();
 private $_mh  = array();

 function __construct()
 { $this->_mh = curl_multi_init(); }

 function add($url)
 {
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_HEADER, 0);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_TIMEOUT, 30);
  curl_multi_add_handle($this->_mh, $ch);
  $this->_handles[] = $ch;
  return $this;
 }

 function run()
 {
  $running=null;
  do {
   curl_multi_exec($this->_mh, $running);
   usleep (250000);
  } while ($running > 0);
  for($i=0; $i < count($this->_handles); $i++) {
   $out = curl_multi_getcontent($this->_handles[$i]);
   $data[$i] = json_decode($out);
   curl_multi_remove_handle($this->_mh, $this->_handles[$i]);
  }
  curl_multi_close($this->_mh);
  return $data;
  }
 }

 $fork = new Fork;

 $output = $fork->add("http://yips.idevcloud.com/Samples/async/fork.php?t=1")
 ->add("http://yips.idevcloud.com/Samples/async/fork.php?t=2")
 ->add("http://yips.idevcloud.com/Samples/async/fork.php?t=3")
 ->run();

 echo "<pre>";
 print_r($output);
 echo "</pre>";
?> 

XMLSERVICE direct call async (Yes and Yes)

2) Yes — Note: No direct DB2 call, but, using index.php/fork.php technique prior would also work async call XMLSERVICE (also work PHP Toolkit interface using DB2 default)

fork.php (modify to fit need):
<?php
function xmlservice($xml) {
  global $i5persistentconnect, $database, $user, $password, $ipc, $ctl;
  $xmlIn = $xml;
  $xmlOut = '';
  if ($i5persistentconnect) $procConn = db2_pconnect($database, $user, $password);   // persistent/pooled connection
  else $procConn = db2_connect($database, $user, $password);                         // full open/close connection
  if (!$procConn) die("Bad connect: $database, $user");
  $stmt = db2_prepare($procConn, "call XMLSERVICE.iPLUG5M(?,?,?,?)"); // Call XMLSERVICE 
                                                                      // stored procedure interface
                                                                      // in/out parameter (xmlOut)
                                                                      // sizes: iPLUG4K - iPLUG15M
  if (!$stmt) die("Bad prepare: ".db2_stmt_errormsg());
  $ret=db2_bind_param($stmt, 1, "ipc", DB2_PARAM_IN);     // ? - /tmp/raw_$user (*sbmjob)
  $ret=db2_bind_param($stmt, 2, "ctl", DB2_PARAM_IN);     // ? - *here or *sbmjob
  $ret=db2_bind_param($stmt, 3, "xmlIn", DB2_PARAM_IN);   // ? - XML input script
  $ret=db2_bind_param($stmt, 4, "xmlOut", DB2_PARAM_OUT); // ? - XML output return
  $ret=db2_execute($stmt);
  if (!$ret) die("Bad execute: ".db2_stmt_errormsg());
  return $xmlOut;
}
?>
2) Yes — direct call xmlservice REST can do it all, async db2, async pgm call, async anything … try the program below, works ‘async’ with yips machine “as is”.
As you can see, we/XMLSERVICE have REST interface (yips http://yips.idevcloud.com/cgi-bin/xmlcgi.pgm), therefore XMLSERVICE naturally works with the async application featured, removed JSON parser on output $out, because we are xml baby. Better yet, xmlservice does much more than DB2 queries ‘async’, in fact, any other bloody thing you want to call ‘async’ (PGM, CMD, PASE, whatever).
<?php
// curl_async.php
class Fork
{
    private $_handles = array();
    private $_mh      = array();

    function __construct()
    {
        $this->_mh = curl_multi_init();
    }

    function add($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_multi_add_handle($this->_mh, $ch);
        $this->_handles[] = $ch;
        return $this;
    }

    function run()
    {
        $running=null;
        do {
            curl_multi_exec($this->_mh, $running);
            usleep (250000);
        } while ($running > 0);
        for($i=0; $i < count($this->_handles); $i++) {
            $out = curl_multi_getcontent($this->_handles[$i]);
            $data[$i] = $out;
            curl_multi_remove_handle($this->_mh, $this->_handles[$i]);
        }
        curl_multi_close($this->_mh);
        return $data;
    }
}

$fork = new Fork;


$output = $fork->add(urlme(xml1()))
    ->add(urlme(xml2()))
    ->add(urlme(xml3()))
    ->run();

echo "<pre>";
print_r($output);
echo "</pre>";


function urlme($clobIn) {
  $parm  = "?db2=*LOCAL";
  $parm .= "&uid=*NONE";
  $parm .= "&pwd=*NONE";
  $parm .= "&ipc=*NA";
  $parm .= "&ctl=*here";
  $parm .= "&xmlin=".urlencode($clobIn);
  $parm .= "&xmlout=512000";  // size expected XML output
  $linkme = "http://yips.idevcloud.com//cgi-bin/xmlcgi.pgm".htmlentities($parm);
  echo $linkme;
  return $linkme;
}


function xml1() {
$xml = <<< XMLME
<?xml version='1.0'?>
<script>
<pgm name='ZZCALL' lib='XMLSERVICE'>
 <parm><data type='1A'>a</data></parm>
 <parm><data type='1A'>b</data></parm>
 <parm><data type='7p4'>11.1111</data></parm>
 <parm><data type='12p2'>222.22</data></parm>
 <parm>
  <ds>
   <data type='1A'>x</data>
   <data type='1A'>y</data>
   <data type='7p4'>66.6666</data>
   <data type='12p2'>77777.77</data>
  </ds>
 </parm>
 <return><data type='10i0'>0</data></return>
</pgm>
</script>
XMLME;
return $xml;
}


function xml2() {
$xml = <<< XMLME
<?xml version='1.0'?>
<script>
<script>
<sql>
<options options='noauto' autocommit='off'/>
<connect conn='myconn' options='noauto'/>
<prepare conn='myconn'>select * from xmlservtst/animal where WEIGHT > 1.0</prepare>
<execute/>
<describe desc='col'/>
<fetch block='all' desc='on'/>
</sql>
</script>
XMLME;
return $xml;
}


function xml3() {
$xml = <<< XMLME
<?xml version='1.0'?>
<script>
<script>
<sql>
<options options='noauto' autocommit='off'/>
<connect conn='myconn' options='noauto'/>
<query conn='myconn'>select * from xmlservtst/animal</query>
<describe desc='col'/>
<fetch block='all' desc='on'/>
</sql>
</script>
XMLME;
return $xml;
}
?>