Skip to content

Commit

Permalink
fix: Added $minChunkNumber to chunkWithQueue mixin (#29)
Browse files Browse the repository at this point in the history
* misc: Added $minChunkNumber to chunkWithQueue mixin

* fix: Fixed phpstan

* fix: Fixed phpstan
  • Loading branch information
YaroslavNahirnyi authored Mar 26, 2024
1 parent 711cfad commit 83511c7
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 8 deletions.
2 changes: 1 addition & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ parameters:
message: '#Call to protected method .+#i'
path: '*Mixin.php'
-
message: '#Access to .* property .+Mixin::.+#i'
message: '#Access to .* property .+Mixin.*::.+#i'
path: '*Mixin.php'
-
message: '#Method .+Mixin::.+ invoked with \d parameters, \d required.#i'
Expand Down
1 change: 0 additions & 1 deletion src/Jobs/HandleChunkJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ public function handle(): void
: new SimpleQueuedChunkHandler($this->handler->getHandler());

if (is_callable($handler)) {
/* @phpstan-ignore-next-line Refactor handlers to fix these */
$handler($items);
} else {
/* @phpstan-ignore-next-line Refactor handlers to fix these */
Expand Down
15 changes: 14 additions & 1 deletion src/Mixins/EloquentBuilderMixin.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,24 @@ public function chunkWithQueue(): callable
->first($settings->queryOptions->keyName)
)->{$settings->queryOptions->attributeKeyName};

$minKeyValue = optional(
DB::query()
->fromSub(
($settings->queryOptions->getMinKeyValueFromNewModelQuery ? $this->getModel()->newQuery() : $this->clone())
->toBase()
->orderBy($settings->queryOptions->keyName)
->limit(1),
$this->getModel()->getTable()
)
->first($settings->queryOptions->keyName)
)->{$settings->queryOptions->attributeKeyName} ?? 1;

if (!$maxKeyValue) {
return true;
}

$maxChunkNumber = (int) ceil($maxKeyValue / $settings->chunkOptions->pieceSize);
$minChunkNumber = max((int) floor($minKeyValue / $settings->chunkOptions->pieceSize), 1);

$params = new ChunkParams(
$handler,
Expand All @@ -299,7 +312,7 @@ public function chunkWithQueue(): callable

$builder = new SerializableBuilder($query);

for ($chunkNumber = 1; $chunkNumber <= $maxChunkNumber; $chunkNumber++) {
for ($chunkNumber = $minChunkNumber; $chunkNumber <= $maxChunkNumber; $chunkNumber++) {
dispatch(new GenerateChunksJob($builder, $params, $chunkNumber))
->onQueue($settings->queueOptions->pieceQueue)
->delay($settings->queueOptions->delay ? $settings->queueOptions->delay * ($chunkNumber - 1) : null);
Expand Down
5 changes: 3 additions & 2 deletions src/Settings/ChunkWithQueue/QueryOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public function __construct(
public readonly string $keyName,
string $attributeKeyName = null,
public readonly bool $getMaxKeyValueFromNewModelQuery = false,
public readonly bool $getMinKeyValueFromNewModelQuery = false,
) {
$this->attributeKeyName = $attributeKeyName ?? Str::contains($this->keyName, '.')
? trim(explode('.', $this->keyName)[1], '\'"')
Expand All @@ -27,8 +28,8 @@ public static function defaultInstance(): self
return new self('id');
}

public static function defaultInstanceWithMaxIdFromBaseQuery(): self
public static function defaultInstanceFromWholeTableQuery(): self
{
return new self('id', null, true);
return new self('id', null, true, true);
}
}
8 changes: 5 additions & 3 deletions tests/EloquentBuilderMixin/ChunkWithQueueTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,27 +106,29 @@ public function testMultipleJobsWithTableNameInQuerySettingsSuccess(): void
Queue::assertPushed(GenerateChunksJob::class, 2);
}

public function testWithMaxIdFromBaseQuery(): void
public function testGenerateJobsForWholeQuery(): void
{
Queue::fake();

$this->generateTestModel();
$this->generateTestModel(fn (TestStubFactory $factory) => $factory->hasChildren(TestStubFactory::new()));
$this->generateTestModel();

$settings = ChunkWithQueueSettings::defaultSettings();
$settings->chunkOptions->chunkSize = 1;
$settings->chunkOptions->pieceSize = 1;
$settings->queryOptions = QueryOptions::defaultInstanceWithMaxIdFromBaseQuery();
$settings->queryOptions = QueryOptions::defaultInstanceFromWholeTableQuery();

TestStub::query()->whereHas('children')->chunkWithQueue(HandlerStub::class, $settings);

Queue::assertPushed(GenerateChunksJob::class, 3);
Queue::assertPushed(GenerateChunksJob::class, 4);
}

public function testWithMaxIdFromGivenQuery(): void
{
Queue::fake();

$this->generateTestModel();
$this->generateTestModel(fn (TestStubFactory $factory) => $factory->hasChildren(TestStubFactory::new()));
$this->generateTestModel();

Expand Down

0 comments on commit 83511c7

Please sign in to comment.