<?php
/*
* This file is part of Chevere.
*
* (c) Rodolfo Berrios <rodolfo@chevere.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chevere\Xr\Traits;
use function Chevere\Message\message;
use Chevere\Xr\Exceptions\XrStopException;
use Chevere\Xr\Interfaces\XrCurlInterface;
use Chevere\Xr\Interfaces\XrMessageInterface;
use Chevere\Xr\XrCurl;
trait XrClientTrait
{
private XrCurlInterface $curl;
public function __construct(
private string $host = 'localhost',
private int $port = 27420,
) {
$this->curl = new XrCurl();
}
public function withCurl(XrCurlInterface $curl): self
{
$new = clone $this;
$new->curl = $curl;
return $new;
}
public function curl(): XrCurlInterface
{
return $this->curl;
}
public function getUrl(string $endpoint): string
{
return "http://{$this->host}:{$this->port}/{$endpoint}";
}
public function sendMessage(XrMessageInterface $message): void
{
try {
$curl = $this->getCurlHandle(
'message',
$message->toArray()
);
$curl->exec();
} finally {
unset($curl);
}
}
public function sendPause(XrMessageInterface $message): void
{
try {
$curl = $this->getCurlHandle(
'lock-post',
$message->toArray()
);
$curl->exec();
$curlError = $curl->error();
if ($curlError === '') {
do {
sleep(1);
} while ($this->isLocked($message));
}
} finally {
unset($curl);
}
}
public function isLocked(XrMessageInterface $message): bool
{
try {
$curl = $this->getCurlHandle(
'locks',
['id' => $message->id()]
);
$curlResult = $curl->exec();
if (!$curlResult || $curl->error() !== '') {
return false;
}
$response = json_decode($curlResult);
if ($response->stop ?? false) {
throw new XrStopException(
message('[STOP EXECUTION] triggered from %remote%')
->strtr('%remote%', $this->host . ':' . $this->port)
);
}
return boolval($response->lock ?? false);
} finally {
unset($curl);
}
return false;
}
/**
* @codeCoverageIgnore
*/
public function exit(int $exitCode = 0): void
{
exit($exitCode);
}
private function getCurlHandle(string $endpoint, array $data): XrCurlInterface
{
$this->curl->setOptArray(
[
CURLINFO_HEADER_OUT => true,
CURLOPT_ENCODING => '',
CURLOPT_FAILONERROR => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($data),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_TIMEOUT => 2,
CURLOPT_URL => $this->getUrl($endpoint),
CURLOPT_USERAGENT => 'chevere/xr 1.0',
]
);
return $this->curl;
}
}
|