Skip to content

Commit 00dae44

Browse files
committed
feat: add gzip compression support for HTTP requests in ClickHouse adapter
1 parent 38faead commit 00dae44

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

src/Usage/Adapter/ClickHouse.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ class ClickHouse extends SQL
6969
/** @var array<array{sql: string, params: array<string, mixed>, duration: float, timestamp: float, success: bool, error?: string}> Query execution log */
7070
private array $queryLog = [];
7171

72+
/** @var bool Whether to enable gzip compression for HTTP requests/responses */
73+
private bool $enableCompression = false;
74+
7275
/**
7376
* @param string $host ClickHouse host
7477
* @param string $username ClickHouse username (default: 'default')
@@ -139,6 +142,19 @@ public function enableQueryLogging(bool $enable = true): self
139142
return $this;
140143
}
141144

145+
/**
146+
* Enable or disable gzip compression for HTTP requests/responses.
147+
* When enabled, responses from ClickHouse will be gzip-compressed, reducing bandwidth usage.
148+
*
149+
* @param bool $enable Whether to enable compression
150+
* @return self
151+
*/
152+
public function setCompression(bool $enable): self
153+
{
154+
$this->enableCompression = $enable;
155+
return $this;
156+
}
157+
142158
/**
143159
* Get the query execution log.
144160
*
@@ -490,6 +506,11 @@ private function query(string $sql, array $params = []): string
490506
// Update the database header for each query (in case setDatabase was called)
491507
$this->client->addHeader('X-ClickHouse-Database', $this->database);
492508

509+
// Enable compression if configured
510+
if ($this->enableCompression) {
511+
$this->client->addHeader('Accept-Encoding', 'gzip');
512+
}
513+
493514
// Build multipart form data body with query and parameters
494515
// The Fetch client will automatically encode arrays as multipart/form-data
495516
$body = ['query' => $sql];
@@ -554,6 +575,11 @@ private function insert(string $table, array $data): void
554575
$this->client->addHeader('X-ClickHouse-Database', $this->database);
555576
$this->client->addHeader('Content-Type', 'application/x-ndjson');
556577

578+
// Enable compression if configured
579+
if ($this->enableCompression) {
580+
$this->client->addHeader('Accept-Encoding', 'gzip');
581+
}
582+
557583
// Join JSON strings with newlines
558584
$body = implode("\n", $data);
559585

tests/Usage/Adapter/ClickHouseTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,4 +539,59 @@ public function testSetTimeoutAboveMaximum(): void
539539
$adapter = new ClickHouseAdapter($host, $username, $password, $port);
540540
$adapter->setTimeout(600001); // Above maximum
541541
}
542+
543+
/**
544+
* Test compression functionality
545+
*/
546+
public function testCompression(): void
547+
{
548+
// Create a new adapter instance with compression enabled
549+
$host = getenv('CLICKHOUSE_HOST') ?: 'clickhouse';
550+
$username = getenv('CLICKHOUSE_USER') ?: 'default';
551+
$password = getenv('CLICKHOUSE_PASSWORD') ?: 'clickhouse';
552+
$port = (int) (getenv('CLICKHOUSE_PORT') ?: 8123);
553+
$secure = (bool) (getenv('CLICKHOUSE_SECURE') ?: false);
554+
555+
$adapter = new ClickHouseAdapter($host, $username, $password, $port, $secure);
556+
$adapter->setNamespace('utopia_usage_compression_test');
557+
$adapter->setTenant(1);
558+
559+
if ($database = getenv('CLICKHOUSE_DATABASE')) {
560+
$adapter->setDatabase($database);
561+
}
562+
563+
$usage = new Usage($adapter);
564+
$usage->setup();
565+
566+
// Test enabling compression
567+
$result = $adapter->setCompression(true);
568+
$this->assertInstanceOf(ClickHouseAdapter::class, $result);
569+
570+
// Test disabling compression
571+
$result = $adapter->setCompression(false);
572+
$this->assertInstanceOf(ClickHouseAdapter::class, $result);
573+
574+
// Enable compression for all subsequent operations
575+
$adapter->setCompression(true);
576+
577+
// Insert data using logBatch with compression enabled
578+
$batchResult = $usage->logBatch([
579+
['metric' => 'compression.test.batch', 'value' => 50, 'period' => '1h', 'tags' => ['type' => 'batch']],
580+
['metric' => 'compression.test.batch', 'value' => 75, 'period' => '1h', 'tags' => ['type' => 'batch']],
581+
['metric' => 'compression.test.single', 'value' => 100, 'period' => '1h', 'tags' => ['type' => 'single']],
582+
]);
583+
$this->assertTrue($batchResult);
584+
585+
// Verify find query works with compression (returns array)
586+
$metrics = $usage->find([]);
587+
$this->assertIsArray($metrics);
588+
589+
// Verify count query works with compression (returns int)
590+
$count = $usage->count([]);
591+
$this->assertIsInt($count);
592+
593+
// Verify sum operation works with compression (returns int)
594+
$sum = $usage->sumByPeriod('compression.test.batch', '1h');
595+
$this->assertIsInt($sum);
596+
}
542597
}

0 commit comments

Comments
 (0)