Skip to content

Commit

Permalink
Merge pull request #3 from Sammyjo20/feature/dispatch-all-helper
Browse files Browse the repository at this point in the history
Feature | Dispatch all helper
  • Loading branch information
Sammyjo20 authored Sep 18, 2022
2 parents 6fec17b + 6758ea9 commit 7f9493a
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 21 deletions.
48 changes: 31 additions & 17 deletions .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,34 @@ protected function handleChunk(Chunk $chunk): void
- **isEmpty:** Specifies if the chunk is empty, which means the totalItems property is zero.
- **isNotEmpty:** Opposite of isEmpty

## Dispatching

To dispatch a chunkable job, it's exactly the same. The default behaviour of chunkable jobs is to process one job, then dispatch the next after it has been successfully processed.

```php
<?php

GetPageOfPokemon::dispatch();
```

## Dispatching every chunked job at once

Sometimes you may want to throw as much resource as you can to a specific chunked job. If processing one chunk at a time is not suitable and you would rather dispatch every chunk straight away, you can use the `dispatchAllChunks` static method on the chunkable job. It will accept constructor arguments through the parameters. Alternatively, you can use the `BulkChunkDispatcher` class.

```php
<?php

use Sammyjo20\LaravelHaystack\BulkChunkDispatcher;

// Will dispatch all jobs at once 🚀

GetPageOfPokemon::dispatchAllChunks();

// or

BulkChunkDispatcher::dispatch(new GetPageOfPokemon);
```

## Stopping Chunking Early

Sometimes you might want to stop the chunking process early. You can use the `stopChunking` method and the job won’t dispatch the next chunk.
Expand Down Expand Up @@ -180,20 +208,6 @@ dispatch($job);

If you would like to execute some logic before the chunking starts, you can extend the `setUp` method on your chunkable job which will be run once.

## Dispatching every chunked job at once

Sometimes you may want to throw as much resource as you can to a specific chunked job. If processing one chunk at a time is not suitable and you would rather dispatch every chunk straight away, you can use the `BulkChunkDispatcher`.

```php
<?php

use Sammyjo20\LaravelHaystack\BulkChunkDispatcher;

// Will dispatch all jobs at once 🚀

BulkChunkDispatcher::dispatch(new GetPageOfPokemon);
```

## Using `ChunkRange` to iterate over all chunks

If you need to iterate over every chunk, you can use the `ChunkRange` class. This will return a generator that you can iterate over to get every chunk.
Expand Down Expand Up @@ -233,10 +247,10 @@ class GetPageOfPokemon extends ChunkableJob implements ShouldQueue
// Keep processing
// When ready to stop:

if ($stop === true) {
$this->stopChunking();
if ($stop === true) {
$this->stopChunking();
}
}
}
}
```

Expand Down
12 changes: 12 additions & 0 deletions src/ChunkableJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,18 @@ public function setNextChunk(?Chunk $nextChunk): ChunkableJob
return $this;
}

/**
* Dispatch all chunks at once
*
* @param ...$arguments
* @return void
* @throws Exceptions\BulkChunkDispatcherException
*/
public static function dispatchAllChunks(...$arguments): void
{
BulkChunkDispatcher::dispatch(new static(...$arguments));
}

/**
* Define the chunk. If it's null or a chunk with zero items the chunkable job will stop early.
*
Expand Down
20 changes: 16 additions & 4 deletions tests/Feature/BulkChunkDispatcherTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@

use Sammyjo20\ChunkableJobs\Chunk;
use Illuminate\Support\Facades\Bus;
use Sammyjo20\ChunkableJobs\BulkChunkDispatcher;
use Sammyjo20\ChunkableJobs\Tests\Fixtures\PaginatedJob;
use Sammyjo20\ChunkableJobs\Tests\Fixtures\UnknownSizeJob;
use Sammyjo20\ChunkableJobs\Tests\Fixtures\ConstructorArgsJob;
use Sammyjo20\ChunkableJobs\Exceptions\BulkChunkDispatcherException;

test('it will dispatch all jobs at once', function () {
Bus::fake();

BulkChunkDispatcher::dispatch(new PaginatedJob);
PaginatedJob::dispatchAllChunks();

Bus::assertDispatchedTimes(PaginatedJob::class, 3);
});

test('the dispatched jobs wont run the next chain', function () {
BulkChunkDispatcher::dispatch(new PaginatedJob);
PaginatedJob::dispatchAllChunks();

$chunkOne = cache()->get('1');
$chunkTwo = cache()->get('2');
Expand All @@ -43,5 +43,17 @@
$this->expectException(BulkChunkDispatcherException::class);
$this->expectExceptionMessage('You cannot iterate through an UnknownSizeChunk.');

BulkChunkDispatcher::dispatch(new UnknownSizeJob);
UnknownSizeJob::dispatchAllChunks();
});

test('arguments are passed into the constructor from dispatch all chunks method', function () {
ConstructorArgsJob::dispatchAllChunks('Sammy');

$chunkOne = cache()->get('1');
$chunkTwo = cache()->get('2');
$chunkThree = cache()->get('3');

expect($chunkOne)->toEqual('Sammy');
expect($chunkTwo)->toEqual('Sammy');
expect($chunkThree)->toEqual('Sammy');
});
34 changes: 34 additions & 0 deletions tests/Fixtures/ConstructorArgsJob.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php declare(strict_types=1);

namespace Sammyjo20\ChunkableJobs\Tests\Fixtures;

use Illuminate\Bus\Queueable;
use Sammyjo20\ChunkableJobs\Chunk;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Sammyjo20\ChunkableJobs\ChunkableJob;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class ConstructorArgsJob extends ChunkableJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

/**
* @param string $name
*/
public function __construct(public string $name)
{
//
}

public function defineChunk(): ?Chunk
{
return new Chunk(30, 10);
}

protected function handleChunk(Chunk $chunk): void
{
cache()->put($chunk->position, $this->name);
}
}

0 comments on commit 7f9493a

Please sign in to comment.