Skip to content

Commit

Permalink
Avoid possible infinite loops on APCu eviction
Browse files Browse the repository at this point in the history
If we are unlucky with an APCu eviction at the wrong moment, and no
other thread writing to the same metric, we can get stuck in an
infinite loop where apcu_fetch will always return false.

Fix by applying the same strategy as if apcu_fetch was false in the
first place (before doing compare-and-swap)

Signed-off-by: Tobias Bengtsson <[email protected]>
  • Loading branch information
TobiasBengtsson committed Nov 9, 2023
1 parent 735ace7 commit 8cf901d
Showing 1 changed file with 15 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/Prometheus/Storage/APC.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ public function updateHistogram(array $data): void
$old = apcu_fetch($sumKey);
if ($old !== false) {
$done = apcu_cas($sumKey, $old, $this->toBinaryRepresentationAsInteger($this->fromBinaryRepresentationAsInteger($old) + $data['value']));
} else {
$new = apcu_add($sumKey, $this->toBinaryRepresentationAsInteger(0));

// If sum does not exist, assume a new histogram and store the metadata
if ($new) {
apcu_store($this->metaKey($data), json_encode($this->metaData($data)));
}
}
}

Expand Down Expand Up @@ -139,6 +146,11 @@ public function updateGauge(array $data): void
$old = apcu_fetch($valueKey);
if ($old !== false) {
$done = apcu_cas($valueKey, $old, $this->toBinaryRepresentationAsInteger($this->fromBinaryRepresentationAsInteger($old) + $data['value']));
} else {
$new = apcu_add($valueKey, $this->toBinaryRepresentationAsInteger(0));
if ($new) {
apcu_store($this->metaKey($data), json_encode($this->metaData($data)));
}
}
}
}
Expand All @@ -162,6 +174,9 @@ public function updateCounter(array $data): void
$old = apcu_fetch($valueKey);
if ($old !== false) {
$done = apcu_cas($valueKey, $old, $this->toBinaryRepresentationAsInteger($this->fromBinaryRepresentationAsInteger($old) + $data['value']));
} else {
apcu_add($this->valueKey($data), 0);
apcu_store($this->metaKey($data), json_encode($this->metaData($data)));
}
}
}
Expand Down

0 comments on commit 8cf901d

Please sign in to comment.