Skip to content

Commit

Permalink
Improve annotations
Browse files Browse the repository at this point in the history
This allows Psalm to cover completly the codebase to help in future
refactorings.
  • Loading branch information
LeSuisse committed Apr 27, 2020
1 parent c627dc1 commit 42509de
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 55 deletions.
74 changes: 41 additions & 33 deletions src/Storage/APCUStore.php
Expand Up @@ -184,25 +184,27 @@ private function metaData(MetricName $name, string $help, LabelNames $labelNames
private function collectCounters() : array
{
$counters = [];
/** @psalm-var array{value:string} $counter */
foreach (new APCuIterator('/^prom:counter:.*:meta/') as $counter) {
/**
* @psalm-var array{name:string, help:string, labelNames:string[]} $metaData
*/
$metaData = json_decode($counter['value'], true);
$labelNames = [];
foreach ($metaData['labelNames'] as $labelName) {
$labelNames[] = (string) $labelName;
}
$labelNames = $metaData['labelNames'];

$data = [
'name' => (string) $metaData['name'],
'help' => (string) $metaData['help'],
'name' => $metaData['name'],
'help' => $metaData['help'],
'labelNames' => $labelNames,
'samples' => [],
];

/** @psalm-var array{key:string,value:int} $value */
foreach (new APCuIterator('/^prom:counter:' . $metaData['name'] . ':.*:value/') as $value) {
$parts = explode(':', $value['key']);
$labelValues = $parts[3];
$data['samples'][] = [
'name' => (string) $metaData['name'],
'name' => $metaData['name'],
'labelNames' => [],
'labelValues' => $this->decodeLabelValues($labelValues),
'value' => $this->fromInteger($value['value']),
Expand All @@ -227,24 +229,26 @@ private function collectCounters() : array
private function collectGauges() : array
{
$gauges = [];
/** @psalm-var array{value:string} $gauge */
foreach (new APCuIterator('/^prom:gauge:.*:meta/') as $gauge) {
/**
* @psalm-var array{name:string, help:string, labelNames:string[]} $metaData
*/
$metaData = json_decode($gauge['value'], true);
$labelNames = [];
foreach ($metaData['labelNames'] as $labelName) {
$labelNames[] = (string) $labelName;
}
$labelNames = $metaData['labelNames'];

$data = [
'name' => (string) $metaData['name'],
'help' => (string) $metaData['help'],
'name' => $metaData['name'],
'help' => $metaData['help'],
'labelNames' => $labelNames,
'samples' => [],
];
/** @psalm-var array{key:string,value:int} $value */
foreach (new APCuIterator('/^prom:gauge:' . $metaData['name'] . ':.*:value/') as $value) {
$parts = explode(':', $value['key']);
$labelValues = $parts[3];
$data['samples'][] = [
'name' => (string) $metaData['name'],
'name' => $metaData['name'],
'labelNames' => [],
'labelValues' => $this->decodeLabelValues($labelValues),
'value' => $this->fromInteger($value['value']),
Expand All @@ -269,16 +273,17 @@ private function collectGauges() : array
private function collectHistograms() : array
{
$histograms = [];
/** @psalm-var array{value:string} $histogram */
foreach (new APCuIterator('/^prom:histogram:.*:meta/') as $histogram) {
/**
* @psalm-var array{name:string, help:string, labelNames:string[], buckets:array<string|float>} $metaData
*/
$metaData = json_decode($histogram['value'], true);
$labelNames = [];
foreach ($metaData['labelNames'] as $labelName) {
$labelNames[] = (string) $labelName;
}
$labelNames = $metaData['labelNames'];

$data = [
'name' => (string) $metaData['name'],
'help' => (string) $metaData['help'],
'name' => $metaData['name'],
'help' => $metaData['help'],
'labelNames' => $labelNames,
'buckets' => $metaData['buckets'],
'samples' => [],
Expand All @@ -288,6 +293,7 @@ private function collectHistograms() : array
$data['buckets'][] = '+Inf';

$histogramBuckets = [];
/** @psalm-var array{key:string,value:int} $value */
foreach (new APCuIterator('/^prom:histogram:' . $metaData['name'] . ':.*:value/') as $value) {
$parts = explode(':', $value['key']);
$labelValues = $parts[3];
Expand Down Expand Up @@ -351,20 +357,14 @@ private function collectHistograms() : array
return $histograms;
}

/**
* @param mixed $val
*/
private function toInteger($val) : int
private function toInteger(float $val) : int
{
return unpack('Q', pack('d', $val))[1];
return (int) unpack('Q', pack('d', $val))[1];
}

/**
* @param mixed $val
*/
private function fromInteger($val) : float
private function fromInteger(int $val) : float
{
return unpack('d', pack('Q', $val))[1];
return (float) unpack('d', pack('Q', $val))[1];
}

/**
Expand All @@ -374,9 +374,16 @@ private function fromInteger($val) : float
*/
private static function sortSamples(array &$samples) : void
{
usort($samples, static function (array $a, array $b) : int {
return strcmp(implode('', $a['labelValues']), implode('', $b['labelValues']));
});
usort(
$samples,
/**
* @psalm-param array{labelValues: string[]} $a
* @psalm-param array{labelValues: string[]} $b
*/
static function (array $a, array $b) : int {
return strcmp(implode('', $a['labelValues']), implode('', $b['labelValues']));
}
);
}

/**
Expand All @@ -394,6 +401,7 @@ private function encodeLabelValues(array $values) : string
*/
private function decodeLabelValues(string $values) : array
{
/** @psalm-var string[] */
return json_decode((string) base64_decode($values, true), true, JSON_THROW_ON_ERROR);
}
}
32 changes: 26 additions & 6 deletions src/Storage/InMemoryStore.php
Expand Up @@ -26,9 +26,21 @@

final class InMemoryStore implements Store, CounterStorage, GaugeStorage, HistogramStorage, FlushableStorage
{
/** @var array<string,mixed> */
/**
* @var array<string,string[][]>
* @psalm-var array<string, array{
* meta: array{name:string, help:string, labelNames:string[]},
* samples: array<string, float>
* }>
*/
private $counters = [];
/** @var array<string,mixed> */
/**
* @var array<string,string[][]>
* @psalm-var array<string, array{
* meta: array{name:string, help:string, labelNames:string[]},
* samples: array<string, float>
* }>
*/
private $gauges = [];
/**
* @var array<string,string[][]>
Expand Down Expand Up @@ -149,7 +161,7 @@ private function collectHistograms() : array
* @psalm-param array<
* string,
* array{
* meta:array{name:string, help:string, type:string, labelNames:string[]},
* meta:array{name:string, help:string, labelNames:string[]},
* samples:array<string, float>
* }
* > $metrics
Expand All @@ -176,9 +188,16 @@ private function internalCollect(string $type, array $metrics) : array
];
}

usort($data['samples'], static function (array $a, array $b) : int {
return strcmp(implode('', $a['labelValues']), implode('', $b['labelValues']));
});
usort(
$data['samples'],
/**
* @psalm-param array{labelValues: string[]} $a
* @psalm-param array{labelValues: string[]} $b
*/
static function (array $a, array $b) : int {
return strcmp(implode('', $a['labelValues']), implode('', $b['labelValues']));
}
);
$samples = [];
foreach ($data['samples'] as $sampleData) {
$samples[] = new Sample($sampleData['name'], $sampleData['value'], $sampleData['labelNames'], $sampleData['labelValues']);
Expand Down Expand Up @@ -336,6 +355,7 @@ private function encodeLabelValues(array $values) : string
*/
private function decodeLabelValues(string $values) : array
{
/** @psalm-var string[] */
return json_decode((string) base64_decode($values, true), true, 512, JSON_THROW_ON_ERROR);
}
}
68 changes: 52 additions & 16 deletions src/Storage/RedisStore.php
Expand Up @@ -51,6 +51,7 @@ public function flush() : void
$membersToRemove[] = $this->redis->sMembers($storageMainKey);
}

/** @psalm-var string[] $membersToRemove */
$membersToRemove = array_merge([], ...$membersToRemove);
$redis = $this->redis->multi();
$redis->del($membersToRemove);
Expand Down Expand Up @@ -159,15 +160,20 @@ public function incrementCounter(MetricName $name, float $value, string $help, M
}

/**
* @return array<int,mixed>
* @return array<int,array<string,mixed>>
*
* @psalm-return array<array{name:string, help:string, labelNames: string[], type:'histogram', samples: list<array{name:string, labelNames:list<string>, labelValues: string[], value: int}>}>
*/
private function collectHistograms() : array
{
/** @var string[] $keys */
$keys = $this->redis->sMembers($this->prefix . 'histogram' . self::PROMETHEUS_METRIC_KEYS_SUFFIX);

$histograms = [];
foreach ($keys as $key) {
$raw = $this->redis->hGetAll($key);
/** @psalm-var array{__meta:string, string:int} $raw */
$raw = $this->redis->hGetAll($key);
/** @psalm-var array{name:string, help:string, labelNames: string[], buckets:float[]} $histogram */
$histogram = json_decode($raw['__meta'], true);
$histogram['type'] = 'histogram';
unset($raw['__meta']);
Expand All @@ -178,6 +184,7 @@ private function collectHistograms() : array

$allLabelValues = [];
foreach (array_keys($raw) as $k) {
/** @psalm-var array{b:string, labelValues:string[]} $d */
$d = json_decode($k, true);
if ($d['b'] === 'sum') {
continue;
Expand All @@ -188,6 +195,7 @@ private function collectHistograms() : array

// We need set semantics.
// This is the equivalent of array_unique but for arrays of arrays.
/** @var array<string[]> $allLabelValues */
$allLabelValues = array_map('unserialize', array_unique(array_map('serialize', $allLabelValues)));
sort($allLabelValues);

Expand Down Expand Up @@ -240,63 +248,91 @@ private function collectHistograms() : array
}

/**
* @return array<int,mixed>
* @return array<int,array<string,mixed>>
*
* @psalm-return array<array{name:string, help:string, labelNames: string[], type:'gauge', samples: list<array{name:string, labelNames:array<empty,empty>, labelValues: string[], value: float}>}>
*/
private function collectGauges() : array
{
/** @var string[] $keys */
$keys = $this->redis->sMembers($this->prefix . 'gauge' . self::PROMETHEUS_METRIC_KEYS_SUFFIX);

$gauges = [];
foreach ($keys as $key) {
$raw = $this->redis->hGetAll($key);
/** @psalm-var array{__meta:string,string:string} $raw */
$raw = $this->redis->hGetAll($key);
/** @psalm-var array{name:string, help:string, labelNames: string[]} $gauge */
$gauge = json_decode($raw['__meta'], true);
$gauge['type'] = 'gauge';
unset($raw['__meta']);
$gauge['samples'] = [];
foreach ($raw as $k => $value) {
/** @var string[] $labelValues */
$labelValues = json_decode($k, true);
$gauge['samples'][] = [
'name' => $gauge['name'],
'labelNames' => [],
'labelValues' => json_decode($k, true),
'value' => $value,
'labelValues' => $labelValues,
'value' => (float) $value,
];
}

usort($gauge['samples'], static function (array $a, array $b) : int {
return strcmp(implode('', $a['labelValues']), implode('', $b['labelValues']));
});
usort(
$gauge['samples'],
/**
* @psalm-param array{labelValues: string[]} $a
* @psalm-param array{labelValues: string[]} $b
*/
static function (array $a, array $b) : int {
return strcmp(implode('', $a['labelValues']), implode('', $b['labelValues']));
}
);
$gauges[] = $gauge;
}

return $gauges;
}

/**
* @return array<int,mixed>
* @return array<int,array<string,mixed>>
*
* @psalm-return array<array{name:string, help:string, labelNames: string[], type:'counter', samples: list<array{name:string, labelNames:array<empty,empty>, labelValues: string[], value: float}>}>
*/
private function collectCounters() : array
{
/** @var string[] $keys */
$keys = $this->redis->sMembers($this->prefix . 'counter' . self::PROMETHEUS_METRIC_KEYS_SUFFIX);

$counters = [];
foreach ($keys as $key) {
$raw = $this->redis->hGetAll($key);
/** @psalm-var array{__meta:string,string:string} $raw */
$raw = $this->redis->hGetAll($key);
/** @psalm-var array{name:string, help:string, labelNames: string[]} $counter */
$counter = json_decode($raw['__meta'], true);
$counter['type'] = 'counter';
unset($raw['__meta']);
$counter['samples'] = [];
foreach ($raw as $k => $value) {
/** @var string[] $labelValues */
$labelValues = json_decode($k, true);
$counter['samples'][] = [
'name' => $counter['name'],
'labelNames' => [],
'labelValues' => json_decode($k, true),
'value' => $value,
'labelValues' => $labelValues,
'value' => (float) $value,
];
}

usort($counter['samples'], static function (array $a, array $b) : int {
return strcmp(implode('', $a['labelValues']), implode('', $b['labelValues']));
});
usort(
$counter['samples'],
/**
* @psalm-param array{labelValues: string[]} $a
* @psalm-param array{labelValues: string[]} $b
*/
static function (array $a, array $b) : int {
return strcmp(implode('', $a['labelValues']), implode('', $b['labelValues']));
}
);
$counters[] = $counter;
}

Expand Down

0 comments on commit 42509de

Please sign in to comment.