Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ $config = Config::fromArray([
| `track_file_operations` | boolean | `true` | Track file operations |
| `proxy` | string | `null` | HTTP/HTTPS proxy for Perfbase API calls |
| `timeout` | int | `10` | Timeout seconds for Perfbase API calls |
| `async` | boolean | `true` | Send traces to Perfbase API asynchronously |

## License

Expand Down
11 changes: 1 addition & 10 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,6 @@ class Config
*/
public int $timeout = 10;

/**
* Enable asynchronous delivery of profiling data
* @var bool
*/
public bool $async_delivery = true;


/**
* @param string|null $api_key
* @param string|null $api_url
Expand All @@ -168,7 +161,6 @@ class Config
* @param bool|null $track_file_operations
* @param string|null $proxy
* @param int|null $timeout
* @param bool|null $async_delivery
*/
public function __construct(
?string $api_key = null,
Expand All @@ -189,8 +181,7 @@ public function __construct(
?bool $track_aws_sdk = null,
?bool $track_file_operations = null,
?string $proxy = null,
?int $timeout = null,
?bool $async_delivery = null
?int $timeout = null
)
{
// Get all the properties of this class
Expand Down
44 changes: 10 additions & 34 deletions src/Http/ApiClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
namespace Perfbase\SDK\Http;

use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Promise\PromiseInterface;
use GuzzleHttp\Promise\Utils;
use JsonException;
use Perfbase\SDK\Config;
use Perfbase\SDK\Exception\PerfbaseApiKeyMissingException;
Expand All @@ -30,12 +28,6 @@ class ApiClient
*/
private GuzzleClient $httpClient;

/**
* Promises to settle before the client is destroyed
* @var array<PromiseInterface>
*/
private array $promises = [];

/**
* @throws PerfbaseApiKeyMissingException
*/
Expand All @@ -46,24 +38,25 @@ public function __construct(Config $config)
}

$this->config = $config;

$this->defaultHeaders = [
'Authorization' => 'Bearer ' . $this->config->api_key,
'Accept' => 'application/json',
'User-Agent' => 'Perfbase-PHP-SDK/1.0',
'Content-Type' => 'application/json',
'Connection' => 'keep-alive',
];

/** @var array<string, mixed> $httpClientConfig */
$httpClientConfig = [];

$httpClientConfig['base_uri'] = $config->api_url;
$httpClientConfig['timeout'] = $config->timeout;

// Set up proxy if configured
if ($config->proxy) {
$httpClientConfig['proxy'] = $config->proxy;
}

// Set up the HTTP client
$this->httpClient = new GuzzleClient($httpClientConfig);
}

Expand All @@ -72,12 +65,10 @@ public function __construct(Config $config)
*
* @param string $endpoint API endpoint to send the request to
* @param array<mixed> $data Data to send in the request body
* @param bool $async If true, send asynchronously; if false, wait for response
*
* @return string|null Response data from the API, or null if non-blocking
* @throws JsonException When the HTTP request fails or returns an error
* @return void
* @throws JsonException
*/
private function post(string $endpoint, array $data, bool $async = true): ?string
private function submit(string $endpoint, array $data): void
{
// Prepare request options
$options = [
Expand All @@ -86,38 +77,23 @@ private function post(string $endpoint, array $data, bool $async = true): ?strin
];

try {
if ($async) {
$this->promises[] = $this->httpClient->postAsync($endpoint, $options);
return null;
} else {
$response = $this->httpClient->post($endpoint, $options);
return (string)$response->getBody();
}
$this->httpClient->post($endpoint, $options);
} catch (Throwable $e) {
// throw new PerfbaseException('HTTP Request failed: ' . $e->getMessage());
}
return null;
}

/**
* Submits a trace to the Perfbase API
*
* @param array<mixed> $data Data to send in the request body
* @param bool $async If true, send asynchronously; if false, wait for response
* @return void
*
* @return string|null Response data from the API, or null if non-blocking
* @throws JsonException When the HTTP request fails or returns an error
*/
public function submitTrace(array $data, bool $async = true): ?string
public function submitTrace(array $data): void
{
return $this->post('/v1/submit', $data, $async);
$this->submit('/v1/submit', $data);
}

public function __destruct()
{
// Attempt to settle all outstanding async HTTP promises without blocking
if (!empty($this->promises)) {
Utils::settle($this->promises)->wait(false);
}
}
}
4 changes: 2 additions & 2 deletions src/Tracing/TraceInstance.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public function __destruct()
* The data is automatically sent to the Perfbase API for analysis.
* @param bool $andSend If true, send the collected data to the API; if false, do not send
* @throws PerfbaseStateException
* @throws JsonException
*/
public function stopProfiling(bool $andSend = true): void
{
Expand Down Expand Up @@ -136,8 +137,7 @@ public function stopProfiling(bool $andSend = true): void
public function sendProfilingData(): void
{
$this->apiClient->submitTrace(
$this->transformData(),
$this->config->async_delivery
$this->transformData()
);
}

Expand Down
65 changes: 0 additions & 65 deletions tests/ApiClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,69 +48,4 @@ public function testInitializesWithValidApiKey(): void
$this->assertInstanceOf(ApiClient::class, $apiClient);
}

/**
* @return void
* @throws PerfbaseApiKeyMissingException
* @throws JsonException
* @covers ::get
*/
public function testSendsSynchronousSubmitRequestAndReturnsResponse(): void
{
$mock = new MockHandler([
new Response(200, [], 'Success'),
]);
$handlerStack = HandlerStack::create($mock);
$guzzleClient = new GuzzleClient(['handler' => $handlerStack]);

$config = new Config();
$config->api_key = 'test_api_key';

$apiClient = new ApiClient($config);
$reflection = new ReflectionClass($apiClient);
$property = $reflection->getProperty('httpClient');
$property->setAccessible(true);
$property->setValue($apiClient, $guzzleClient);

$response = $apiClient->submitTrace(['key' => 'value'], false);

$this->assertSame('Success', $response);
}

/**
* @return void
* @throws JsonException
* @throws PerfbaseApiKeyMissingException
* @covers ::post
*/
public function testSendsAsynchronousSubmitRequestAndDoesNotBlock(): void
{
$mock = new MockHandler([
new Response(200, [], 'Success'),
]);
$handlerStack = HandlerStack::create($mock);
$guzzleClient = new GuzzleClient(['handler' => $handlerStack]);

$config = new Config();
$config->api_key = 'test_api_key';

$apiClient = new ApiClient($config);
$reflection = new ReflectionClass($apiClient);
$property = $reflection->getProperty('httpClient');
$property->setAccessible(true);
$property->setValue($apiClient, $guzzleClient);

$response = $apiClient->submitTrace(['key' => 'value'], true);

$this->assertNull($response);

// Check if promises array is populated
$promisesProperty = $reflection->getProperty('promises');
$promisesProperty->setAccessible(true);

/** @var array<PromiseInterface> $promises */
$promises = $promisesProperty->getValue($apiClient);
$this->assertIsArray($promises);
$this->assertCount(1, $promises);
$this->assertInstanceOf(PromiseInterface::class, $promises[0]);
}
}
1 change: 0 additions & 1 deletion tests/ConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ public function testConstructorSetsProperties(): void
$this->assertFalse($config->track_file_operations);
$this->assertSame('http://proxy:8080', $config->proxy);
$this->assertSame(1000, $config->timeout);
$this->assertFalse($config->async_delivery);
}

/**
Expand Down
Loading