Skip to content

Commit

Permalink
feat: add tr() function
Browse files Browse the repository at this point in the history
  • Loading branch information
roxblnfk committed May 24, 2024
1 parent 78873fb commit 12d3d95
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 4 deletions.
15 changes: 15 additions & 0 deletions src/Client/TrapHandle.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Buggregator\Trap\Client\TrapHandle\Counter;
use Buggregator\Trap\Client\TrapHandle\Dumper as VarDumper;
use Buggregator\Trap\Client\TrapHandle\StaticState;
use Buggregator\Trap\Support\Tick;
use Symfony\Component\VarDumper\Caster\TraceStub;

/**
Expand Down Expand Up @@ -35,6 +36,20 @@ public static function fromArray(array $array): self
return new self($array);
}

/**
* Create a new instance with a single value.
*
* @param int<0, max> $number The tick number.
* @param float $delta The time delta between the current and previous tick.
*/
public static function fromTicker(int $number, float $delta, int $memory): self
{
$self = new self([]);
$self->values[] = new Tick($number, $delta, $memory, $self->staticState->stackTrace[0]);

return $self;
}

/**
* Dump only if the condition is true.
* The check is performed immediately upon declaration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

declare(strict_types=1);

namespace Buggregator\Trap\Support;
namespace Buggregator\Trap\Support\Caster;

use Buggregator\Trap\Support\Caster\EnumValue;
use Google\Protobuf\Internal\Descriptor as InternalDescriptor;
use Google\Protobuf\Descriptor as PublicDescriptor;
use Google\Protobuf\Internal\Descriptor as InternalDescriptor;
use Google\Protobuf\Internal\DescriptorPool;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\MapField;
Expand Down
23 changes: 23 additions & 0 deletions src/Support/Caster/TickerCaster.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Buggregator\Trap\Support\Caster;

use Buggregator\Trap\Support\Tick;
use Symfony\Component\VarDumper\Cloner\Stub;

/**
* @internal
*/
final class TickerCaster
{
public static function cast(Tick $tick, array $a, Stub $stub, bool $isNested): mixed
{
$stub->type = $stub::TYPE_REF;
$stub->class = $tick->__toString();
$stub->attr = $tick->line;

return [];
}
}
62 changes: 62 additions & 0 deletions src/Support/Tick.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace Buggregator\Trap\Support;

/**
* Data object representing a tick.
*
* @see tr()
* @internal
*/
final class Tick
{
/**
* @param int<0, max> $number The tick number.
* @param float $delta The time delta between the current and previous tick.
* @param int $memory The memory usage.
* @param array{
* function?: string,
* line?: int,
* file?: string,
* class?: class-string,
* type?: string,
* args?: list<mixed>
* } $line The stack trace line.
*/
public function __construct(
public readonly int $number,
public readonly float $delta,
public readonly int $memory,
public readonly array $line,
) {
}

public function __toString(): string
{
// Format delta
$delta = $this->delta;
$deltaStr = match (true) {
$delta === 0.0 => '-.---',
$delta < 0.001 => \sprintf('+%.3fms', $delta * 1000),
$delta < 0.01 => \sprintf('+%.2fms', $delta * 1000),
$delta < 1 => \sprintf('+%.1fms', ($delta * 1000)),
$delta < 10 => \sprintf('+%.2fs', $delta),
$delta < 60 => \sprintf('+%.3fs', $delta),
default => \sprintf('+%dm %ds', (int) $delta % 60, (int) $delta % 60),
};

return \sprintf(
"Tick #%d %s %sM",
$this->number,
$deltaStr,
\number_format(
$this->memory / 1024 / 1024,
2,
'.',
'_',
),
);
}
}
44 changes: 43 additions & 1 deletion src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

use Buggregator\Trap\Client\TrapHandle;
use Buggregator\Trap\Support\Caster\EnumValue;
use Buggregator\Trap\Support\ProtobufCaster;
use Buggregator\Trap\Support\Caster\ProtobufCaster;
use Buggregator\Trap\Support\Caster\TickerCaster;
use Buggregator\Trap\Support\Tick;
use Google\Protobuf\Internal\MapField;
use Google\Protobuf\Internal\Message;
use Google\Protobuf\Internal\RepeatedField;
Expand All @@ -26,6 +28,44 @@ function trap(mixed ...$values): TrapHandle
// do nothing
}

try {
/**
* Send values into Buggregator and return the first value.
*
* When arguments are passed it equals to {@see trap()} with `->return()` method call.
* When no arguments passed, it calculates ticks, time between the last `tr()` call and memory usage.
*
* @param mixed ...$values
*/
function tr(mixed ...$values): mixed
{
static $counter = -1;
static $time = 0;

++$counter;

try {
if ($values === []) {
$previous = $time;
$mem = $time = \microtime(true);
return TrapHandle::fromTicker(
$counter,
$counter === 0 ? 0 : $mem - $previous,
memory_get_usage(),
)->return();
}

$mem = $time = \microtime(true);
/** @psalm-suppress InternalMethod */
return TrapHandle::fromArray($values)->return();
} finally {
$mem === $time and $time = \microtime(true);
}
}
} catch (\Throwable $e) {
// do nothing
}

/**
* Register the var-dump caster for protobuf messages
*/
Expand All @@ -38,4 +78,6 @@ function trap(mixed ...$values): TrapHandle
AbstractCloner::$defaultCasters[MapField::class] ??= [ProtobufCaster::class, 'castMap'];
/** @psalm-suppress MixedAssignment */
AbstractCloner::$defaultCasters[EnumValue::class] ??= [ProtobufCaster::class, 'castEnum'];
/** @psalm-suppress MixedAssignment */
AbstractCloner::$defaultCasters[Tick::class] ??= [TickerCaster::class, 'cast'];
}

0 comments on commit 12d3d95

Please sign in to comment.