blob: 1fa60a7d21249044af980a792c2764720fc99026 [file] [log] [blame]
<?php
/*
*
* Copyright 2017 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* PHP client for QPS testing works as follows:
* 1. Gets initiated by a call from a proxy that implements the worker service. The
* argument to this client is the proxy connection information
* 2. Initiate an RPC to the proxy to get ClientConfig
* 3. Initiate a client-side telemetry RPC to the proxy
* 4. Parse the client config, which includes server target information and then start
* a unary or streaming test as appropriate.
* 5. After each completed RPC, send its timing to the proxy. The proxy does all histogramming
* 6. Proxy will respond on the timing channel when it's time to complete. Our
* next timing write will fail and we know that it's time to stop
* The above complex dance is since threading and async are not idiomatic and we
* shouldn't ever be waiting to read a mark
*
* This test only supports a single channel since threading/async is not idiomatic
* This test supports unary or streaming ping-pongs, as well as open-loop
*
*/
require dirname(__FILE__).'/vendor/autoload.php';
require dirname(__FILE__).'/histogram.php';
/**
* Assertion function that always exits with an error code if the assertion is
* falsy.
*
* @param $value Assertion value. Should be true.
* @param $error_message Message to display if the assertion is false
*/
function hardAssert($value, $error_message)
{
if (!$value) {
echo $error_message."\n";
exit(1);
}
}
function hardAssertIfStatusOk($status)
{
if ($status->code !== Grpc\STATUS_OK) {
echo "Call did not complete successfully. Status object:\n";
var_dump($status);
exit(1);
}
}
/* Start the actual client */
function qps_client_main($proxy_address, $server_ind) {
echo "[php-client] Initiating php client\n";
$proxystubopts = [];
$proxystubopts['credentials'] = Grpc\ChannelCredentials::createInsecure();
$proxystub = new Grpc\Testing\ProxyClientServiceClient($proxy_address, $proxystubopts);
list($config, $status) = $proxystub->GetConfig(new Grpc\Testing\PBVoid())->wait();
hardAssertIfStatusOk($status);
hardAssert($config->getOutstandingRpcsPerChannel() == 1, "Only 1 outstanding RPC supported");
echo "[php-client] Got configuration from proxy, target is '$server_ind'th server" . $config->getServerTargets()[$server_ind] . "\n";
$histres = $config->getHistogramParams()->getResolution();
$histmax = $config->getHistogramParams()->getMaxPossible();
$stubopts = [];
if ($config->getSecurityParams()) {
if ($config->getSecurityParams()->getUseTestCa()) {
$stubopts['credentials'] = Grpc\ChannelCredentials::createSsl(
file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
} else {
$stubopts['credentials'] = Grpc\ChannelCredentials::createSsl(null);
}
$override = $config->getSecurityParams()->getServerHostOverride();
if ($override) {
$stubopts['grpc.ssl_target_name_override'] = $override;
$stubopts['grpc.default_authority'] = $override;
}
} else {
$stubopts['credentials'] = Grpc\ChannelCredentials::createInsecure();
}
echo "[php-client] Initiating php benchmarking client\n";
$stub = new Grpc\Testing\BenchmarkServiceClient(
$config->getServerTargets()[$server_ind], $stubopts);
$req = new Grpc\Testing\SimpleRequest();
$req->setResponseType(Grpc\Testing\PayloadType::COMPRESSABLE);
$req->setResponseSize($config->getPayloadConfig()->getSimpleParams()->getRespSize());
$payload = new Grpc\Testing\Payload();
$payload->setType(Grpc\Testing\PayloadType::COMPRESSABLE);
$payload->setBody(str_repeat("\0", $config->getPayloadConfig()->getSimpleParams()->getReqSize()));
$req->setPayload($payload);
/* TODO(stanley-cheung): Enable the following by removing the 0&& once protobuf
* properly supports oneof in PHP */
if (0 && $config->getLoadParams()->getLoad() == "poisson") {
$poisson = true;
$lamrecip = 1.0/($config->getLoadParams()->getPoisson()->getOfferedLoad());
$issue = microtime(true) + $lamrecip * -log(1.0-rand()/(getrandmax()+1));
} else {
$poisson = false;
}
$histogram = new Histogram($histres, $histmax);
$histogram->clean();
$count = 0;
$histogram_result = new Grpc\Testing\HistogramData;
$telehist = $proxystub->ReportHist();
if ($config->getRpcType() == Grpc\Testing\RpcType::UNARY) {
while (1) {
if ($poisson) {
time_sleep_until($issue);
$issue = $issue + $lamrecip * -log(1.0-rand()/(getrandmax()+1));
}
$startreq = microtime(true);
list($resp,$status) = $stub->UnaryCall($req)->wait();
hardAssertIfStatusOk($status);
$histogram->add((microtime(true)-$startreq)*1e9);
$count += 1;
if ($count == 2000) {
$contents = $histogram->contents();
$histogram_result->setBucket($contents);
$histogram_result->setMinSeen($histogram->minimum());
$histogram_result->setMaxSeen($histogram->maximum());
$histogram_result->setSum($histogram->sum());
$histogram_result->setSumOfSquares($histogram->sum_of_squares());
$histogram_result->setCount($histogram->count());
$telehist->write($histogram_result);
$histogram->clean();
$count = 0;
}
}
} else {
$stream = $stub->StreamingCall();
while (1) {
if ($poisson) {
time_sleep_until($issue);
$issue = $issue + $lamrecip * -log(1.0-rand()/(getrandmax()+1));
}
$startreq = microtime(true);
$stream->write($req);
$resp = $stream->read();
$histogram->add((microtime(true)-$startreq)*1e9);
$count += 1;
if ($count == 2000) {
$contents = $histogram->contents();
$histogram_result->setBucket($contents);
$histogram_result->setMinSeen($histogram->minimum());
$histogram_result->setMaxSeen($histogram->maximum());
$histogram_result->setSum($histogram->sum());
$histogram_result->setSumOfSquares($histogram->sum_of_squares());
$histogram_result->setCount($histogram->count());
$telehist->write($histogram_result);
$histogram->clean();
$count = 0;
}
}
}
}
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
error_reporting(-1);
qps_client_main($argv[1], $argv[2]);