Issues (320)

demo/client/parallel.php (5 issues)

Labels
Severity
1
<?php
2
require_once __DIR__ . "/_prepend.php";
3
4
use PhpXmlRpc\Encoder;
5
use PhpXmlRpc\Client;
6
use PhpXmlRpc\PhpXmlRpc;
7
use PhpXmlRpc\Request;
8
use PhpXmlRpc\Response;
9
10
/// @todo add an html header with links to view-source
11
12
/**
13
 * A class taking advantage of cURL to send many requests in parallel (to a single server), for when the given server
14
 * does not support the system.multicall method
15
 */
16
class ParallelClient extends Client
17 1
{
18
    public function sendParallel($requests, $timeout = 0, $method = '')
19 1
    {
20 1
        if ($method == '') {
21
            $method = $this->method;
22
        }
23
24
        if ($timeout == 0) {
25 1
            $timeout = $this->timeout;
26 1
        }
27
28 1
        $opts = $this->getOptions();
29 1
        $opts['timeout'] = $timeout;
30
31 1
        /// @todo validate that $method can be handled by the current curl install
32 1
33 1
        $handles = array();
34 1
        $curl = curl_multi_init();
35
36 1
        foreach($requests as $k => $req) {
37 1
            $req->setDebug($this->debug);
38 1
            $handle = $this->createCurlHandle($req, $method, $this->server, $this->port, $this->path, $opts);
39 1
            curl_multi_add_handle($curl, $handle);
0 ignored issues
show
It seems like $curl can also be of type true; however, parameter $multi_handle of curl_multi_add_handle() does only seem to accept CurlMultiHandle|resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

39
            curl_multi_add_handle(/** @scrutinizer ignore-type */ $curl, $handle);
Loading history...
It seems like $handle can also be of type false; however, parameter $handle of curl_multi_add_handle() does only seem to accept CurlHandle|resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

39
            curl_multi_add_handle($curl, /** @scrutinizer ignore-type */ $handle);
Loading history...
40 1
            $handles[$k] = $handle;
41 1
        }
42 1
43 1
        $running = 0;
44 1
        do {
45 1
            curl_multi_exec($curl, $running);
0 ignored issues
show
It seems like $curl can also be of type true; however, parameter $multi_handle of curl_multi_exec() does only seem to accept CurlMultiHandle|resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

45
            curl_multi_exec(/** @scrutinizer ignore-type */ $curl, $running);
Loading history...
46 1
        } while($running > 0);
47 1
48
        $responses = array();
49 1
        $errors = array();
50 1
        foreach($handles as $k => $h) {
51 1
            $responses[$k] = curl_multi_getcontent($handles[$k]);
52 1
53
            if ($this->debug > 1) {
54 1
                $message = "---CURL INFO---\n";
55 1
                foreach (curl_getinfo($h) as $name => $val) {
56
                    if (is_array($val)) {
57
                        $val = implode("\n", $val);
58 1
                    }
59
                    $message .= $name . ': ' . $val . "\n";
60 1
                }
61 1
                $message .= '---END---';
62
                $this->getLogger()->debugMessage($message);
63 1
            }
64 1
65 1
            if (!$responses[$k]) {
66
                $errors[$k] = curl_error($h);
67 1
            }
68
69
            //curl_close($h);
70
            curl_multi_remove_handle($curl, $h);
0 ignored issues
show
It seems like $curl can also be of type true; however, parameter $multi_handle of curl_multi_remove_handle() does only seem to accept CurlMultiHandle|resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

70
            curl_multi_remove_handle(/** @scrutinizer ignore-type */ $curl, $h);
Loading history...
71
        }
72
        curl_multi_close($curl);
0 ignored issues
show
It seems like $curl can also be of type true; however, parameter $multi_handle of curl_multi_close() does only seem to accept CurlMultiHandle|resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

72
        curl_multi_close(/** @scrutinizer ignore-type */ $curl);
Loading history...
73
74
        foreach($responses as $k => $resp) {
75
            if (!$resp) {
76
                $responses[$k] = new Response(0, PhpXmlRpc::$xmlrpcerr['curl_fail'], PhpXmlRpc::$xmlrpcstr['curl_fail'] . ': ' . $errors[$k]);
77
            } else {
78
                $responses[$k] = $requests[$k]->parseResponse($resp, true, $this->return_type);
79
            }
80 1
        }
81
82 1
        return $responses;
83
    }
84 1
}
85 1
86
// a minimal benchmark - use 3 strategies to execute the same 25 calls: sequentially, using parallel http requests, and
87
// using a single system.multiCall request
88 1
89
$num_tests = 25;
90
91
$data = array(1, 1.0, 'hello world', true, '20051021T23:43:00', -1, 11.0, '~!@#$%^&*()_+|', false, '20051021T23:43:00');
92 1
$encoder = new Encoder();
93
$value = $encoder->encode($data, array('auto_dates'));
94
$req = new Request('interopEchoTests.echoValue', array($value));
95
$reqs = array();
96 1
for ($i = 0; $i < $num_tests; $i++) {
97
    $reqs[] = $req;
98 1
}
99 1
100 1
$client = new ParallelClient(XMLRPCSERVER);
101 1
102 1
// avoid storing http info in the responses, to make the checksums comparable
103 1
$client->setDebug(-1);
104 1
105
echo "Making $num_tests calls to method interopEchoTests.echoValue on server " . XMLRPCSERVER . " ...\n";
106
flush();
107 1
108 1
$client->setOption(Client::OPT_NO_MULTICALL,  true);
109
$t = microtime(true);
110 1
$resp = $client->send($reqs);
111 1
$t = microtime(true) - $t;
112 1
echo "Sequential send: " . sprintf('%.3f', $t) . " secs.\n";
113 1
echo "Response checksum: " . md5(var_export($resp, true)) . "\n";
114
flush();
115 1
116 1
if (strpos(XMLRPCSERVER, 'http://') === 0) {
117 1
    $client->setOption(Client::OPT_USE_CURL,  Client::USE_CURL_ALWAYS);
118 1
    $t = microtime(true);
119
    $resp = $client->send($reqs);
120 1
    $t = microtime(true) - $t;
121 1
    echo "Sequential send, curl (w. keepalive): " . sprintf('%.3f', $t) . " secs.\n";
122 1
    echo "Response checksum: " . md5(var_export($resp, true)) . "\n";
123 1
    flush();
124 1
}
125
126 1
$t = microtime(true);
127
$resp = $client->sendParallel($reqs);
128
$t = microtime(true) - $t;
129
echo "Parallel send: " . sprintf('%.3f', $t) . " secs.\n";
130
echo "Response checksum: " . md5(var_export($resp, true)) . "\n";
131
flush();
132
133
$client->setOption(Client::OPT_NO_MULTICALL, false);
134
// make sure we don't reuse the keepalive handle
135
$client->setOption(Client::OPT_USE_CURL,  Client::USE_CURL_NEVER);
136
$t = microtime(true);
137
$resp = $client->send($reqs);
138
$t = microtime(true) - $t;
139
echo "Multicall send: " . sprintf('%.3f', $t) . " secs.\n";
140
echo "Response checksum: " . md5(var_export($resp, true)) . "\n";
141
flush();
142