Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,16 @@ stopping always happens *between* iterations, so your job is never interrupted h
All options are optional. Without limits the worker runs until it is stopped
via `$stop()`, `$worker->stop()` or a SIGTERM signal.

| Option | Type | Description |
|---------------|----------|---------------------------------------------------------------------------------------------------------------------------------|
| `runLimit` | `int` | Stop after this number of iterations. |
| `memoryLimit` | `string` | Stop when memory usage exceeds this value, e.g. `128MB`. Supported units: `B`, `KB`, `MB`, `GB` (case-insensitive, 1024-based). |
| `timeLimit` | `int` | Stop after this number of seconds. |
| Option | Type | Description |
|---------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
| `runLimit` | `int` | Stop after this number of iterations. |
| `memoryLimit` | `string` | Stop when memory usage exceeds this value, e.g. `128MB` or `128M`. Supported units: `B`, `K`/`KB`, `M`/`MB`, `G`/`GB` (case-insensitive, 1024-based). |
| `timeLimit` | `int` | Stop after this number of seconds. |

Limits are checked after each iteration. When a limit is exceeded, the worker logs the reason and stops gracefully.

:::warning
An invalid `memoryLimit` string throws a `Patchlevel\Worker\InvalidFormat` exception.
An invalid or too large `memoryLimit` string throws a `Patchlevel\Worker\InvalidFormat` exception.
:::

:::note
Expand Down
14 changes: 12 additions & 2 deletions src/Bytes.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Patchlevel\Worker;

use function array_key_exists;
use function is_int;
use function preg_match;
use function sprintf;
use function strtoupper;
Expand All @@ -13,8 +14,11 @@ final class Bytes
{
private const SIZES = [
'B' => 1,
'K' => 1_024,
'KB' => 1_024,
'M' => 1_048_576,
'MB' => 1_048_576,
'G' => 1_073_741_824,
'GB' => 1_073_741_824,
];

Expand All @@ -36,14 +40,20 @@ public static function parseFromString(string $string): self
throw new InvalidFormat($string);
}

$number = (int)$matches[1];
$unit = strtoupper($matches[2] ?? 'B');

if (!array_key_exists($unit, self::SIZES)) {
throw new InvalidFormat($string);
}

return new self($number * self::SIZES[$unit]);
$bytes = $matches[1] * self::SIZES[$unit];

// integer overflow results in a float
if (!is_int($bytes)) {
throw new InvalidFormat($string);
}

return new self($bytes);
}

public function formatted(): string
Expand Down
2 changes: 1 addition & 1 deletion src/InvalidFormat.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ final class InvalidFormat extends InvalidArgumentException
{
public function __construct(string $message)
{
parent::__construct(sprintf('Invalid byte format received (got: "%s"). The format must consist of a number and a unit. The following units are allowed: B, KB, MB, GB', $message));
parent::__construct(sprintf('Invalid byte format received (got: "%s"). The format must consist of a number and a unit. The following units are allowed: B, K, KB, M, MB, G, GB', $message));
}
}
13 changes: 13 additions & 0 deletions tests/Unit/BytesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ public static function invalidFormatProvider(): Generator
yield ['-5GB'];
yield ['505Foo'];
yield ['50Kb50'];
yield ['50T'];
yield ['50TB'];
yield ['99999999999GB'];
yield ['99999999999999999999'];
}

#[DataProvider('validParseDataProvider')]
Expand Down Expand Up @@ -55,6 +59,15 @@ public static function validParseDataProvider(): Generator
yield ['50Gb', 53_687_091_200, '50.0 GiB'];
yield ['50gb', 53_687_091_200, '50.0 GiB'];

yield ['50K', 51_200, '50.0 KiB'];
yield ['50k', 51_200, '50.0 KiB'];
yield ['512M', 536_870_912, '512.0 MiB'];
yield ['512m', 536_870_912, '512.0 MiB'];
yield ['1G', 1_073_741_824, '1.0 GiB'];
yield ['1g', 1_073_741_824, '1.0 GiB'];

yield ['0050MB', 52_428_800, '50.0 MiB'];

yield ['1024b', 1024, '1.0 KiB'];
yield ['1024Kb', 1_048_576, '1.0 MiB'];
yield ['1024Mb', 1_073_741_824, '1.0 GiB'];
Expand Down
Loading