Skip to content

Commit

Permalink
Merge pull request #118 from kbond/refactor
Browse files Browse the repository at this point in the history
[BC Break] Refactor
  • Loading branch information
kbond authored Nov 23, 2024
2 parents 0aa911d + 11af66a commit af92ade
Show file tree
Hide file tree
Showing 14 changed files with 224 additions and 177 deletions.
85 changes: 47 additions & 38 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,50 @@

## 0.5.0

Two new `bigint` columns were added to the `processed_messages` table:
`wait_time` and `handle_time`. These are milliseconds. You will need to
create a migration to add these columns to your database. They are not
nullable so your migration will need to account for existing data. You
can either truncate (purge) the `processed_messages` table or have your
migration calculate these values based on the existing data.

Here's a calculation example for MySQL:

```php
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class VersionXXX extends AbstractMigration
{
public function getDescription(): string
{
return 'Add processed_messages.wait_time and handle_time columns';
}

public function up(Schema $schema): void
{
// Add the columns as nullable
$this->addSql('ALTER TABLE processed_messages ADD wait_time BIGINT DEFAULT NULL, ADD handle_time BIGINT DEFAULT NULL');

// set the times from existing data
$this->addSql('UPDATE processed_messages SET wait_time = TIMESTAMPDIFF(SECOND, dispatched_at, received_at) * 1000, handle_time = TIMESTAMPDIFF(SECOND, received_at, finished_at) * 1000');

// Make the columns not nullable
$this->addSql('ALTER TABLE processed_messages CHANGE wait_time wait_time BIGINT NOT NULL, CHANGE handle_time handle_time BIGINT NOT NULL');
}

public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE processed_messages DROP wait_time, DROP handle_time');
}
}
```
* Two new `bigint` columns were added to the `processed_messages` table:
`wait_time` and `handle_time`. These are milliseconds. You will need to
create a migration to add these columns to your database. They are not
nullable so your migration will need to account for existing data. You
can either truncate (purge) the `processed_messages` table or have your
migration calculate these values based on the existing data.

Here's a calculation example for MySQL:

```php
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class VersionXXX extends AbstractMigration
{
public function getDescription(): string
{
return 'Add processed_messages.wait_time and handle_time columns';
}

public function up(Schema $schema): void
{
// Add the columns as nullable
$this->addSql('ALTER TABLE processed_messages ADD wait_time BIGINT DEFAULT NULL, ADD handle_time BIGINT DEFAULT NULL');

// set the times from existing data
$this->addSql('UPDATE processed_messages SET wait_time = TIMESTAMPDIFF(SECOND, dispatched_at, received_at) * 1000, handle_time = TIMESTAMPDIFF(SECOND, received_at, finished_at) * 1000');

// Make the columns not nullable
$this->addSql('ALTER TABLE processed_messages CHANGE wait_time wait_time BIGINT NOT NULL, CHANGE handle_time handle_time BIGINT NOT NULL');
}

public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE processed_messages DROP wait_time, DROP handle_time');
}
}
```
* `ProcessedMessage::timeInQueue()` now returns milliseconds instead of seconds.
* `ProcessedMessage::timeToHandle()` now returns milliseconds instead of seconds.
* `ProcessedMessage::timeToProcess()` now returns milliseconds instead of seconds.
* `Snapshot::averageWaitTime()` now returns milliseconds instead of seconds.
* `Snapshot::averageHandlingTime()` now returns milliseconds instead of seconds.
* `Snapshot::averageProcessingTime()` now returns milliseconds instead of seconds.
* The `results` column in the `processed_messages` table is now nullable. Create
a migration to capture this change. This is to allow for a future feature where
result processing/storage can be disabled.
2 changes: 1 addition & 1 deletion config/doctrine/mapping/ProcessedMessage.orm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
<field name="tags" column="tags" nullable="true" />
<field name="failureType" column="failure_type" nullable="true" />
<field name="failureMessage" column="failure_message" type="text" nullable="true" />
<field name="results" column="results" type="json" />
<field name="results" column="results" type="json" nullable="true" />
</mapped-superclass>
</doctrine-mapping>
4 changes: 2 additions & 2 deletions src/Command/MonitorCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ private function renderSnapshot(SymfonyStyle $io, InputInterface $input): void
$failRate < 10 => \sprintf('<comment>%s%%</comment>', $failRate),
default => \sprintf('<error>%s%%</error>', $failRate),
},
$waitTime ? Helper::formatTime($snapshot->averageWaitTime()) : 'n/a',
$handlingTime ? Helper::formatTime($snapshot->averageHandlingTime()) : 'n/a',
$waitTime ? Helper::formatTime($snapshot->averageWaitTime() / 1000) : 'n/a',
$handlingTime ? Helper::formatTime($snapshot->averageHandlingTime() / 1000) : 'n/a',
\round($snapshot->handledPerMinute(), 2),
\round($snapshot->handledPerHour(), 2),
\round($snapshot->handledPerDay(), 2),
Expand Down
76 changes: 76 additions & 0 deletions src/History/Metric.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

/*
* This file is part of the zenstruck/messenger-monitor-bundle package.
*
* (c) Kevin Bond <kevinbond@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Zenstruck\Messenger\Monitor\History;

/**
* @author Kevin Bond <kevinbond@gmail.com>
*/
abstract class Metric
{
final public function failRate(): float
{
try {
return $this->failureCount() / $this->totalCount();
} catch (\DivisionByZeroError) {
return 0;
}
}

/**
* @param positive-int $divisor Seconds
*/
final public function handledPer(int $divisor): float
{
$interval = $this->totalSeconds() / $divisor;

return $this->totalCount() / $interval;
}

final public function handledPerMinute(): float
{
return $this->handledPer(60);
}

final public function handledPerHour(): float
{
return $this->handledPer(60 * 60);
}

final public function handledPerDay(): float
{
return $this->handledPer(60 * 60 * 24);
}

/**
* @return int milliseconds
*/
final public function averageProcessingTime(): int
{
return $this->averageWaitTime() + $this->averageHandlingTime();
}

/**
* @return int milliseconds
*/
abstract public function averageWaitTime(): int;

/**
* @return int milliseconds
*/
abstract public function averageHandlingTime(): int;

abstract public function failureCount(): int;

abstract public function totalCount(): int;

abstract protected function totalSeconds(): int;
}
47 changes: 21 additions & 26 deletions src/History/Model/MessageTypeMetric.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,62 +11,57 @@

namespace Zenstruck\Messenger\Monitor\History\Model;

use Zenstruck\Messenger\Monitor\History\Metric;
use Zenstruck\Messenger\Monitor\Type;

/**
* @author Kevin Bond <kevinbond@gmail.com>
*/
final class MessageTypeMetric
final class MessageTypeMetric extends Metric
{
public readonly Type $type;
private readonly Type $type;

/**
* @param class-string $class
* @param float $averageWaitTime In seconds
* @param float $averageHandlingTime In seconds
*/
public function __construct(
string $class,
public readonly int $totalCount,
public readonly int $failureCount,
public readonly float $averageWaitTime,
public readonly float $averageHandlingTime,
private readonly int $totalCount,
private readonly int $failureCount,
private readonly int $averageWaitTime,
private readonly int $averageHandlingTime,
private readonly int $totalSeconds,
) {
$this->type = new Type($class);
}

public function failRate(): float
public function type(): Type
{
try {
return $this->failureCount / $this->totalCount;
} catch (\DivisionByZeroError) {
return 0;
}
return $this->type;
}

/**
* @param positive-int $divisor Seconds
*/
public function handledPer(int $divisor): float
public function averageWaitTime(): int
{
$interval = $this->totalSeconds / $divisor;
return $this->averageWaitTime;
}

return $this->totalCount / $interval;
public function averageHandlingTime(): int
{
return $this->averageHandlingTime;
}

public function handledPerMinute(): float
public function failureCount(): int
{
return $this->handledPer(60);
return $this->failureCount;
}

public function handledPerHour(): float
public function totalCount(): int
{
return $this->handledPer(60 * 60);
return $this->totalCount;
}

public function handledPerDay(): float
protected function totalSeconds(): int
{
return $this->handledPer(60 * 60 * 24);
return $this->totalSeconds;
}
}
16 changes: 8 additions & 8 deletions src/History/Model/ProcessedMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,25 +146,25 @@ final public function isFailure(): bool
}

/**
* @return float In seconds
* @return int milliseconds
*/
final public function timeInQueue(): float
final public function timeInQueue(): int
{
return $this->waitTime / 1000;
return $this->waitTime;
}

/**
* @return float In seconds
* @return int milliseconds
*/
final public function timeToHandle(): float
final public function timeToHandle(): int
{
return $this->handleTime / 1000;
return $this->handleTime;
}

/**
* @return float In seconds
* @return int milliseconds
*/
final public function timeToProcess(): float
final public function timeToProcess(): int
{
return $this->timeInQueue() + $this->timeToHandle();
}
Expand Down
62 changes: 7 additions & 55 deletions src/History/Snapshot.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
/**
* @author Kevin Bond <kevinbond@gmail.com>
*/
final class Snapshot
final class Snapshot extends Metric
{
private int $successCount;
private int $failureCount;
private float $averageWaitTime;
private float $averageHandlingTime;
private int $averageWaitTime;
private int $averageHandlingTime;
private int $totalSeconds;

public function __construct(private Storage $storage, private Specification $specification)
Expand Down Expand Up @@ -68,62 +68,14 @@ public function failureCount(): int
return $this->failureCount ??= $this->storage->count($this->specification->failures());
}

public function failRate(): float
public function averageWaitTime(): int
{
try {
return $this->failureCount() / $this->totalCount();
} catch (\DivisionByZeroError) {
return 0;
}
}

/**
* @return float In seconds
*/
public function averageWaitTime(): float
{
return $this->averageWaitTime ??= $this->storage->averageWaitTime($this->specification) ?? 0.0;
}

/**
* @return float In seconds
*/
public function averageHandlingTime(): float
{
return $this->averageHandlingTime ??= $this->storage->averageHandlingTime($this->specification) ?? 0.0;
}

/**
* @return float In seconds
*/
public function averageProcessingTime(): float
{
return $this->averageWaitTime() + $this->averageHandlingTime();
}

/**
* @param positive-int $divisor Seconds
*/
public function handledPer(int $divisor): float
{
$interval = $this->totalSeconds() / $divisor;

return $this->totalCount() / $interval;
}

public function handledPerMinute(): float
{
return $this->handledPer(60);
}

public function handledPerHour(): float
{
return $this->handledPer(60 * 60);
return $this->averageWaitTime ??= $this->storage->averageWaitTime($this->specification) ?? 0;
}

public function handledPerDay(): float
public function averageHandlingTime(): int
{
return $this->handledPer(60 * 60 * 24);
return $this->averageHandlingTime ??= $this->storage->averageHandlingTime($this->specification) ?? 0;
}

public function totalSeconds(): int
Expand Down
Loading

0 comments on commit af92ade

Please sign in to comment.