Skip to content

Commit 2a4a8dd

Browse files
Bake pause/resume into SpansRecorder with a depth counter
The PausableRecorder trait could only handle a single ignored event with nothing nested under it. Anything trickier (a normal recordStart/recordEnd under a pause, or a second ignored event) silently desynced the resume. Pause/resume is now a feature of SpansRecorder itself. Static $pauseOwner and $pauseDepth track ownership and call depth across the recorder hierarchy. startSpan and endSpan carry the counter math: increments while owner-paused do not produce real spans, and resume fires the moment depth returns to zero. Lifecycle::flush() clears the static state at every subtask/request boundary so long-running runtimes cannot leak pause state across executions.
1 parent 68bdb2a commit 2a4a8dd

9 files changed

Lines changed: 258 additions & 107 deletions

File tree

src/Concerns/Recorders/PausableRecorder.php

Lines changed: 0 additions & 70 deletions
This file was deleted.

src/Recorders/CommandRecorder/CommandRecorder.php

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use Spatie\FlareClient\AttributesProviders\PhpCommandAttributesProvider;
66
use Spatie\FlareClient\AttributesProviders\SymfonyInputCommandAttributesProvider;
7-
use Spatie\FlareClient\Concerns\Recorders\PausableRecorder;
87
use Spatie\FlareClient\Contracts\CommandAttributesProvider;
98
use Spatie\FlareClient\Contracts\EntryPointHandlerProvider;
109
use Spatie\FlareClient\EntryPoint\EntryPointResolver;
@@ -19,8 +18,6 @@
1918

2019
class CommandRecorder extends SpansRecorder
2120
{
22-
use PausableRecorder;
23-
2421
/** @var array<int, string> */
2522
protected array $ignoredCommands = [];
2623

@@ -152,12 +149,6 @@ public function recordEnd(
152149
int $exitCode = 0,
153150
array $attributes = []
154151
): ?Span {
155-
if ($this->pausedTrace()) {
156-
$this->resumeTrace();
157-
158-
return null;
159-
}
160-
161152
return $this->endSpan(additionalAttributes: [
162153
'process.exit_code' => $exitCode,
163154
...$attributes,

src/Recorders/JobRecorder/JobRecorder.php

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace Spatie\FlareClient\Recorders\JobRecorder;
44

55
use Spatie\FlareClient\AttributesProviders\PhpJobAttributesProvider;
6-
use Spatie\FlareClient\Concerns\Recorders\PausableRecorder;
76
use Spatie\FlareClient\Contracts\EntryPointHandlerProvider;
87
use Spatie\FlareClient\Contracts\JobAttributesProvider;
98
use Spatie\FlareClient\EntryPoint\EntryPoint;
@@ -25,8 +24,6 @@
2524

2625
class JobRecorder extends SpansRecorder
2726
{
28-
use PausableRecorder;
29-
3027
/** @var array<int, string> */
3128
protected array $ignoredClasses = [];
3229

@@ -125,12 +122,6 @@ public function recordStartFromJob(
125122

126123
public function recordEnd(array $attributes = []): ?Span
127124
{
128-
if ($this->pausedTrace()) {
129-
$this->resumeTrace();
130-
131-
return null;
132-
}
133-
134125
$span = $this->endSpan(
135126
additionalAttributes: $attributes,
136127
includeMemoryUsage: true,
@@ -147,12 +138,6 @@ public function recordFailed(
147138
Throwable $exception,
148139
array $attributes = [],
149140
): ?Span {
150-
if ($this->pausedTrace()) {
151-
$this->resumeTrace();
152-
153-
return null;
154-
}
155-
156141
$throwableClass = $exception::class;
157142

158143
$trackingUuid = $this->tracer->ids->uuid();

src/Recorders/QueueRecorder/QueueRecorder.php

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
namespace Spatie\FlareClient\Recorders\QueueRecorder;
44

55
use Spatie\FlareClient\AttributesProviders\PhpJobAttributesProvider;
6-
use Spatie\FlareClient\Concerns\Recorders\PausableRecorder;
76
use Spatie\FlareClient\Contracts\JobAttributesProvider;
87
use Spatie\FlareClient\Enums\RecorderType;
98
use Spatie\FlareClient\Enums\SpanType;
@@ -15,8 +14,6 @@
1514

1615
class QueueRecorder extends SpansRecorder
1716
{
18-
use PausableRecorder;
19-
2017
/** @var array<int, string> */
2118
protected array $ignoredClasses = [];
2219

@@ -74,12 +71,6 @@ public function recordStartFromQueuedJob(
7471

7572
public function recordEnd(array $attributes = []): ?Span
7673
{
77-
if ($this->pausedTrace()) {
78-
$this->resumeTrace();
79-
80-
return null;
81-
}
82-
8374
return $this->endSpan(additionalAttributes: $attributes);
8475
}
8576

src/Recorders/SpansRecorder.php

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ abstract class SpansRecorder extends Recorder implements SpansRecorderContract
2525
/** @var array<Span> */
2626
protected array $stack = [];
2727

28+
protected static ?SpansRecorder $pauseOwner = null;
29+
30+
protected static int $pauseDepth = 0;
31+
2832
public function __construct(
2933
protected Tracer $tracer,
3034
protected BackTracer $backTracer,
@@ -69,6 +73,12 @@ final protected function startSpan(
6973
throw new InvalidArgumentException('Either $nameAndAttributes must be set, or both $name and $attributes must be set.');
7074
}
7175

76+
if (self::$pauseOwner === $this) {
77+
self::$pauseDepth++;
78+
79+
return null;
80+
}
81+
7282
$shouldTrace = $this->withTraces && $this->tracer->sampling;
7383
$shouldReport = $this->shouldReport();
7484

@@ -120,6 +130,10 @@ final protected function endSpan(
120130
?Closure $spanCallback = null,
121131
bool $includeMemoryUsage = false,
122132
): ?Span {
133+
if ($this->consumePauseEnd()) {
134+
return null;
135+
}
136+
123137
$span = array_pop($this->stack);
124138

125139
if ($span === null) {
@@ -183,17 +197,17 @@ final protected function span(
183197
time: $start,
184198
);
185199

186-
if ($span === null) {
187-
return null;
188-
}
189-
190200
$this->endSpan(
191201
time: $end,
192202
additionalAttributes: $additionalAttributes === null ? [] : $additionalAttributes,
193203
spanCallback: $spanCallback,
194204
includeMemoryUsage: $includeMemoryUsage,
195205
);
196206

207+
if ($span === null) {
208+
return null;
209+
}
210+
197211
if ($this->withTraces && $this->tracer->sampling === true) {
198212
$this->backtraceEntry($span);
199213
}
@@ -205,4 +219,47 @@ final public function getSpans(): array
205219
{
206220
return $this->entries;
207221
}
222+
223+
public static function resetPauseState(): void
224+
{
225+
self::$pauseOwner = null;
226+
self::$pauseDepth = 0;
227+
}
228+
229+
protected function pauseTrace(): void
230+
{
231+
if (self::$pauseOwner === $this) {
232+
self::$pauseDepth++;
233+
234+
return;
235+
}
236+
237+
if (self::$pauseOwner !== null) {
238+
return;
239+
}
240+
241+
self::$pauseOwner = $this;
242+
self::$pauseDepth = 1;
243+
244+
$this->tracer->pauseSampling();
245+
}
246+
247+
private function consumePauseEnd(): bool
248+
{
249+
if (self::$pauseOwner !== $this) {
250+
return false;
251+
}
252+
253+
self::$pauseDepth--;
254+
255+
if (self::$pauseDepth > 0) {
256+
return true;
257+
}
258+
259+
self::$pauseOwner = null;
260+
261+
$this->tracer->resumeSampling();
262+
263+
return true;
264+
}
208265
}

src/Support/Lifecycle.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Spatie\FlareClient\Enums\SpanType;
1111
use Spatie\FlareClient\Logger;
1212
use Spatie\FlareClient\Memory\Memory;
13+
use Spatie\FlareClient\Recorders\SpansRecorder;
1314
use Spatie\FlareClient\Resources\Resource;
1415
use Spatie\FlareClient\Spans\Span;
1516
use Spatie\FlareClient\Time\Time;
@@ -391,6 +392,8 @@ public function flush(): void
391392
$this->sentReports->clear();
392393
$this->recorders->reset();
393394

395+
SpansRecorder::resetPauseState();
396+
394397
$this->applicationSpan = null;
395398
$this->registeringSpan = null;
396399
$this->bootingSpan = null;

tests/Pest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Spatie\FlareClient\Flare;
66
use Spatie\FlareClient\FlareConfig;
77
use Spatie\FlareClient\FlareProvider;
8+
use Spatie\FlareClient\Recorders\SpansRecorder;
89
use Spatie\FlareClient\Support\Container;
910
use Spatie\FlareClient\Tests\Shared\FakeApi;
1011
use Spatie\FlareClient\Tests\Shared\FakeIds;
@@ -21,6 +22,7 @@
2122
FakeIds::reset();
2223
FakeMemory::reset();
2324
FakeSampler::reset();
25+
SpansRecorder::resetPauseState();
2426
})->in(__DIR__);
2527

2628
function makePathsRelative(string $text): string

0 commit comments

Comments
 (0)