Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
234
src/Framework/Core/ValueObjects/Duration.php
Normal file
234
src/Framework/Core/ValueObjects/Duration.php
Normal file
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Core\ValueObjects;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
final readonly class Duration
|
||||
{
|
||||
private function __construct(
|
||||
private int $nanoseconds
|
||||
) {
|
||||
if ($nanoseconds < 0) {
|
||||
throw new InvalidArgumentException('Duration cannot be negative');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Duration directly from nanoseconds for maximum precision
|
||||
*/
|
||||
public static function fromNanoseconds(int $nanoseconds): self
|
||||
{
|
||||
return new self($nanoseconds);
|
||||
}
|
||||
|
||||
// Factory Methods
|
||||
public static function fromSeconds(float $seconds): self
|
||||
{
|
||||
if ($seconds < 0) {
|
||||
throw new InvalidArgumentException('Duration cannot be negative');
|
||||
}
|
||||
|
||||
return new self((int) round($seconds * 1_000_000_000));
|
||||
}
|
||||
|
||||
public static function fromUnit(float $value, TimeUnit $unit): self
|
||||
{
|
||||
if ($value < 0) {
|
||||
throw new InvalidArgumentException('Duration cannot be negative');
|
||||
}
|
||||
$seconds = $value * $unit->getMultiplierToSeconds();
|
||||
|
||||
return new self((int) round($seconds * 1_000_000_000));
|
||||
}
|
||||
|
||||
public static function fromMilliseconds(float $milliseconds): self
|
||||
{
|
||||
return self::fromUnit($milliseconds, TimeUnit::MILLISECOND);
|
||||
}
|
||||
|
||||
public static function fromMicroseconds(float $microseconds): self
|
||||
{
|
||||
return self::fromUnit($microseconds, TimeUnit::MICROSECOND);
|
||||
}
|
||||
|
||||
public static function fromMinutes(float $minutes): self
|
||||
{
|
||||
return self::fromUnit($minutes, TimeUnit::MINUTE);
|
||||
}
|
||||
|
||||
public static function fromHours(float $hours): self
|
||||
{
|
||||
return self::fromUnit($hours, TimeUnit::HOUR);
|
||||
}
|
||||
|
||||
public static function fromDays(float $days): self
|
||||
{
|
||||
return self::fromUnit($days, TimeUnit::DAY);
|
||||
}
|
||||
|
||||
public static function between(Timestamp $timestamp, Timestamp $other): self
|
||||
{
|
||||
return $timestamp->diff($other);
|
||||
}
|
||||
|
||||
// Parse from human-readable strings
|
||||
public static function parse(string $value): self
|
||||
{
|
||||
$value = trim($value);
|
||||
|
||||
if (preg_match('/^(\d+(?:\.\d+)?)\s*([a-zA-Z]*)$/', $value, $matches)) {
|
||||
$number = (float) $matches[1];
|
||||
$unitString = $matches[2] ?: 's';
|
||||
|
||||
$unit = TimeUnit::fromString($unitString);
|
||||
|
||||
return self::fromUnit($number, $unit);
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException("Invalid duration format: $value");
|
||||
}
|
||||
|
||||
// Conversion Methods
|
||||
public function toSeconds(): float
|
||||
{
|
||||
return $this->nanoseconds / 1_000_000_000;
|
||||
}
|
||||
|
||||
public function toNanoseconds(): int
|
||||
{
|
||||
return $this->nanoseconds;
|
||||
}
|
||||
|
||||
public function toUnit(TimeUnit $unit, int $precision = 2): float
|
||||
{
|
||||
$seconds = $this->nanoseconds / 1_000_000_000;
|
||||
|
||||
return round($seconds / $unit->getMultiplierToSeconds(), $precision);
|
||||
}
|
||||
|
||||
public function toMilliseconds(): float
|
||||
{
|
||||
return $this->toUnit(TimeUnit::MILLISECOND, 0);
|
||||
}
|
||||
|
||||
public function toMicroseconds(): float
|
||||
{
|
||||
return $this->toUnit(TimeUnit::MICROSECOND, 0);
|
||||
}
|
||||
|
||||
public function toMinutes(): float
|
||||
{
|
||||
return $this->toUnit(TimeUnit::MINUTE);
|
||||
}
|
||||
|
||||
public function toHours(): float
|
||||
{
|
||||
return $this->toUnit(TimeUnit::HOUR);
|
||||
}
|
||||
|
||||
// Human-readable format
|
||||
public function toHumanReadable(): string
|
||||
{
|
||||
if ($this->nanoseconds === 0) {
|
||||
return '0s';
|
||||
}
|
||||
|
||||
$seconds = $this->nanoseconds / 1_000_000_000;
|
||||
$unit = TimeUnit::bestUnitFor($seconds);
|
||||
$value = $this->toUnit($unit);
|
||||
|
||||
return $value . ' ' . $unit->value;
|
||||
}
|
||||
|
||||
// Arithmetic Operations
|
||||
public function add(Duration $other): self
|
||||
{
|
||||
return new self($this->nanoseconds + $other->nanoseconds);
|
||||
}
|
||||
|
||||
public function subtract(Duration $other): self
|
||||
{
|
||||
$result = $this->nanoseconds - $other->nanoseconds;
|
||||
if ($result < 0) {
|
||||
throw new InvalidArgumentException('Subtraction would result in negative duration');
|
||||
}
|
||||
|
||||
return new self($result);
|
||||
}
|
||||
|
||||
public function multiply(float $factor): self
|
||||
{
|
||||
if ($factor < 0) {
|
||||
throw new InvalidArgumentException('Factor cannot be negative');
|
||||
}
|
||||
|
||||
return new self((int) round($this->nanoseconds * $factor));
|
||||
}
|
||||
|
||||
// Comparison Methods
|
||||
public function equals(Duration $other): bool
|
||||
{
|
||||
return $this->nanoseconds === $other->nanoseconds;
|
||||
}
|
||||
|
||||
public function greaterThan(Duration $other): bool
|
||||
{
|
||||
return $this->nanoseconds > $other->nanoseconds;
|
||||
}
|
||||
|
||||
public function lessThan(Duration $other): bool
|
||||
{
|
||||
return $this->nanoseconds < $other->nanoseconds;
|
||||
}
|
||||
|
||||
// Utility Methods
|
||||
public function isZero(): bool
|
||||
{
|
||||
return $this->nanoseconds === 0;
|
||||
}
|
||||
|
||||
public function isNotZero(): bool
|
||||
{
|
||||
return $this->nanoseconds > 0;
|
||||
}
|
||||
|
||||
// Framework Integration
|
||||
public function toCacheSeconds(): int
|
||||
{
|
||||
return (int) ceil($this->nanoseconds / 1_000_000_000);
|
||||
}
|
||||
|
||||
public function toTimeoutSeconds(): int
|
||||
{
|
||||
return (int) ceil($this->nanoseconds / 1_000_000_000);
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->toHumanReadable();
|
||||
}
|
||||
|
||||
// Common constants
|
||||
public static function zero(): self
|
||||
{
|
||||
return new self(0);
|
||||
}
|
||||
|
||||
public static function oneSecond(): self
|
||||
{
|
||||
return new self(1_000_000_000);
|
||||
}
|
||||
|
||||
public static function oneMinute(): self
|
||||
{
|
||||
return self::fromMinutes(1);
|
||||
}
|
||||
|
||||
public static function oneHour(): self
|
||||
{
|
||||
return self::fromHours(1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user