Skip to content

Commit

Permalink
Added high resolution time to pipeline report execution time (#1410)
Browse files Browse the repository at this point in the history
  • Loading branch information
norberttech authored Jan 27, 2025
1 parent 41154dd commit 3731b3f
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 5 deletions.
4 changes: 3 additions & 1 deletion src/core/etl/src/Flow/ETL/DataFrame.php
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,7 @@ public function run(?callable $callback = null, bool $analyze = false) : ?Report

if ($analyze) {
$startedAt = $this->context->config->clock()->now();
$startTime = Statistics\HighResolutionTime::now();
}

foreach ($clone->pipeline->process($clone->context) as $rows) {
Expand All @@ -773,8 +774,9 @@ public function run(?callable $callback = null, bool $analyze = false) : ?Report

if ($analyze) {
$endedAt = $this->context->config->clock()->now();
$endTime = Statistics\HighResolutionTime::now();

return new Report($schema, new Statistics($totalRows, new Statistics\ExecutionTime($startedAt, $endedAt)));
return new Report($schema, new Statistics($totalRows, new Statistics\ExecutionTime($startedAt, $endedAt, $startTime->diff($endTime))));
}

return null;
Expand Down
2 changes: 1 addition & 1 deletion src/core/etl/src/Flow/ETL/Dataset/Statistics.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{
public function __construct(
private int $totalRows,
public readonly ExecutionTime $executionTime,
public ExecutionTime $executionTime,
) {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@

final readonly class ExecutionTime
{
public function __construct(public \DateTimeImmutable $startedAt, public \DateTimeImmutable $finishedAt)
{
public function __construct(
public \DateTimeImmutable $startedAt,
public \DateTimeImmutable $finishedAt,
public HighResolutionTime $highResolutionTime,
) {
if ($startedAt > $finishedAt) {
throw new InvalidArgumentException('Execution start date must be before finish date');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

declare(strict_types=1);

namespace Flow\ETL\Dataset\Statistics;

final readonly class HighResolutionTime implements \Stringable
{
/**
* @param int $seconds
* @param int $nanoseconds
*/
public function __construct(public int $seconds, public int $nanoseconds)
{
}

public static function now() : self
{
$timeParts = \hrtime(as_number: false);

return new self($timeParts[0], $timeParts[1]);
}

public function __toString() : string
{
return $this->toString();
}

public function diff(self $other) : self
{
$diffSeconds = $other->seconds - $this->seconds;
$diffNanoseconds = $other->nanoseconds - $this->nanoseconds;

// Adjust for negative nanoseconds
if ($diffNanoseconds < 0) {
$diffNanoseconds += 1_000_000_000;
$diffSeconds--;
}

return new self($diffSeconds, $diffNanoseconds);
}

/**
* @return array<int>
*/
public function toArray() : array
{
return [$this->seconds, $this->nanoseconds];
}

public function toSeconds() : float
{
return $this->seconds + $this->nanoseconds / 1_000_000_000;
}

public function toString() : string
{
$formatted = number_format($this->toSeconds(), 9, '.', '');
$formatted = rtrim($formatted, '0');
$formatted = rtrim($formatted, '.');

return $formatted . 's';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
str_schema};
use Flow\Clock\FakeClock;
use Flow\ETL\Tests\FlowIntegrationTestCase;
use Flow\ETL\{FlowContext, Rows};
use Flow\ETL\{Dataset\Statistics\HighResolutionTime, FlowContext, Rows};

final class AnalyzeTest extends FlowIntegrationTestCase
{
Expand Down Expand Up @@ -63,6 +63,8 @@ public function test_analyzing_csv_file_with_auto_cast() : void
self::assertInstanceOf(\DateTimeImmutable::class, $report->statistics()->executionTime->finishedAt);
self::assertGreaterThanOrEqual($report->statistics()->executionTime->startedAt, $report->statistics()->executionTime->finishedAt);
self::assertEquals(5 * 60, $report->statistics()->executionTime->inSeconds());
self::assertInstanceOf(HighResolutionTime::class, $report->statistics()->executionTime->highResolutionTime);
self::assertgreaterThan(0, $report->statistics()->executionTime->highResolutionTime->toSeconds());
}

public function test_analyzing_csv_file_with_limit() : void
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

declare(strict_types=1);

namespace Flow\ETL\Tests\Unit\Dataset\Statistics;

use Flow\ETL\Dataset\Statistics\HighResolutionTime;
use Flow\ETL\Tests\FlowTestCase;

final class HighResolutionTimeTest extends FlowTestCase
{
public function test_constructor_initializes_correctly() : void
{
$time = new HighResolutionTime(123, 456789000);

self::assertSame([123, 456789000], $time->toArray());
self::assertEquals(123.456789, $time->toSeconds());
}

public function test_diff_when_nanoseconds_need_adjustment() : void
{
$t1 = new HighResolutionTime(10, 500000000); // 10.5s
$t2 = new HighResolutionTime(10, 300000000); // 10.3s

$diff = $t1->diff($t2);

// 10.3s - 10.5s = -0.2s => [-1, 800000000]
self::assertSame([-1, 800000000], $diff->toArray());
self::assertEqualsWithDelta(-0.2, $diff->toSeconds(), 1e-9);
}

public function test_diff_with_no_difference() : void
{
$t1 = new HighResolutionTime(10, 500000000);
$diff = $t1->diff($t1);

self::assertSame([0, 0], $diff->toArray());
self::assertEquals(0.0, $diff->toSeconds());
}

public function test_diff_with_positive_difference() : void
{
$t1 = new HighResolutionTime(10, 500000000); // 10.5s
$t2 = new HighResolutionTime(12, 100000000); // 12.1s

$diff = $t1->diff($t2);

// We expect 1.6s difference
self::assertSame([1, 600000000], $diff->toArray());
self::assertEqualsWithDelta(1.6, $diff->toSeconds(), 1e-9);
}

public function test_now_creates_current_time_instance() : void
{
$time = HighResolutionTime::now();
self::assertInstanceOf(HighResolutionTime::class, $time);
}

public function test_to_formatted_string_removes_trailing_zeroes() : void
{
// 5.250000000 => should display as "5.25"
$time = new HighResolutionTime(5, 250000000);
self::assertSame('5.25s', $time->toString());

// 0.001000000 => should display as "0.001"
$time = new HighResolutionTime(0, 1000000); // 1,000,000ns = 0.001s
self::assertSame('0.001s', $time->toString());

// 3.000000000 => should display as "3"
$time = new HighResolutionTime(3, 0);
self::assertSame('3s', $time->toString());
}
}

0 comments on commit 3731b3f

Please sign in to comment.