master

laravel/framework

Last updated at: 29/12/2023 09:20

PendingBatch.php

TLDR

The provided file, PendingBatch.php, contains the implementation of the PendingBatch class in the Illuminate\Bus namespace. This class is responsible for managing a batch of jobs and executing them asynchronously. It provides methods for adding jobs to the batch, registering callbacks for progress, success, failure, and completion, specifying options for the batch, and dispatching the batch for execution.

Methods

__construct

The constructor method of the PendingBatch class. It initializes the instance with the IoC container and a collection of jobs.

add

Add jobs to the batch. Accepts either an iterable, an object, or an array of jobs. Returns the instance of PendingBatch for method chaining.

progress

Add a callback to be executed after a job in the batch has executed successfully. Returns the instance of PendingBatch for method chaining.

progressCallbacks

Get the "progress" callbacks that have been registered with the pending batch. Returns an array of progress callbacks.

then

Add a callback to be executed after all jobs in the batch have executed successfully. Returns the instance of PendingBatch for method chaining.

thenCallbacks

Get the "then" callbacks that have been registered with the pending batch. Returns an array of then callbacks.

catch

Add a callback to be executed after the first failing job in the batch. Returns the instance of PendingBatch for method chaining.

catchCallbacks

Get the "catch" callbacks that have been registered with the pending batch. Returns an array of catch callbacks.

finally

Add a callback to be executed after the batch has finished executing. Returns the instance of PendingBatch for method chaining.

finallyCallbacks

Get the "finally" callbacks that have been registered with the pending batch. Returns an array of finally callbacks.

allowFailures

Indicate that the batch should not be cancelled when a job within the batch fails. Accepts a boolean value. Returns the instance of PendingBatch for method chaining.

allowsFailures

Determine if the pending batch allows jobs to fail without cancelling the batch. Returns a boolean value.

name

Set the name for the batch. Accepts a string as the batch name. Returns the instance of PendingBatch for method chaining.

onConnection

Specify the queue connection that the batched jobs should run on. Accepts a string as the connection name. Returns the instance of PendingBatch for method chaining.

connection

Get the connection used by the pending batch. Returns a string or null.

onQueue

Specify the queue that the batched jobs should run on. Accepts a string as the queue name. Returns the instance of PendingBatch for method chaining.

queue

Get the queue used by the pending batch. Returns a string or null.

withOption

Add additional data into the batch's options array. Accepts a string as the option key and a value as the option value. Returns the instance of PendingBatch for method chaining.

dispatch

Dispatch the batch. Returns an instance of Illuminate\Bus\Batch. Throws a Throwable exception if an error occurs during dispatching.

dispatchAfterResponse

Dispatch the batch after the response is sent to the browser. Returns an instance of Illuminate\Bus\Batch.

dispatchExistingBatch

Dispatch an existing batch. Accepts an instance of Illuminate\Bus\Batch. Throws a Throwable exception if an error occurs during dispatching. Note that this method is protected, so it cannot be accessed outside the class.

Classes

Class: PendingBatch

The PendingBatch class manages a batch of jobs and provides methods for adding jobs, registering callbacks, specifying options, and dispatching the batch for execution. It also has properties to store the container instance, the batch name, the jobs collection, and the batch options.

<?php

namespace Illuminate\Bus;

use Closure;
use Illuminate\Bus\Events\BatchDispatched;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Traits\Conditionable;
use Laravel\SerializableClosure\SerializableClosure;
use Throwable;

class PendingBatch
{
    use Conditionable;

    /**
     * The IoC container instance.
     *
     * @var \Illuminate\Contracts\Container\Container
     */
    protected $container;

    /**
     * The batch name.
     *
     * @var string
     */
    public $name = '';

    /**
     * The jobs that belong to the batch.
     *
     * @var \Illuminate\Support\Collection
     */
    public $jobs;

    /**
     * The batch options.
     *
     * @var array
     */
    public $options = [];

    /**
     * Create a new pending batch instance.
     *
     * @param  \Illuminate\Contracts\Container\Container  $container
     * @param  \Illuminate\Support\Collection  $jobs
     * @return void
     */
    public function __construct(Container $container, Collection $jobs)
    {
        $this->container = $container;
        $this->jobs = $jobs;
    }

    /**
     * Add jobs to the batch.
     *
     * @param  iterable|object|array  $jobs
     * @return $this
     */
    public function add($jobs)
    {
        $jobs = is_iterable($jobs) ? $jobs : Arr::wrap($jobs);

        foreach ($jobs as $job) {
            $this->jobs->push($job);
        }

        return $this;
    }

    /**
     * Add a callback to be executed after a job in the batch have executed successfully.
     *
     * @param  callable  $callback
     * @return $this
     */
    public function progress($callback)
    {
        $this->options['progress'][] = $callback instanceof Closure
            ? new SerializableClosure($callback)
            : $callback;

        return $this;
    }

    /**
     * Get the "progress" callbacks that have been registered with the pending batch.
     *
     * @return array
     */
    public function progressCallbacks()
    {
        return $this->options['progress'] ?? [];
    }

    /**
     * Add a callback to be executed after all jobs in the batch have executed successfully.
     *
     * @param  callable  $callback
     * @return $this
     */
    public function then($callback)
    {
        $this->options['then'][] = $callback instanceof Closure
                        ? new SerializableClosure($callback)
                        : $callback;

        return $this;
    }

    /**
     * Get the "then" callbacks that have been registered with the pending batch.
     *
     * @return array
     */
    public function thenCallbacks()
    {
        return $this->options['then'] ?? [];
    }

    /**
     * Add a callback to be executed after the first failing job in the batch.
     *
     * @param  callable  $callback
     * @return $this
     */
    public function catch($callback)
    {
        $this->options['catch'][] = $callback instanceof Closure
                    ? new SerializableClosure($callback)
                    : $callback;

        return $this;
    }

    /**
     * Get the "catch" callbacks that have been registered with the pending batch.
     *
     * @return array
     */
    public function catchCallbacks()
    {
        return $this->options['catch'] ?? [];
    }

    /**
     * Add a callback to be executed after the batch has finished executing.
     *
     * @param  callable  $callback
     * @return $this
     */
    public function finally($callback)
    {
        $this->options['finally'][] = $callback instanceof Closure
                    ? new SerializableClosure($callback)
                    : $callback;

        return $this;
    }

    /**
     * Get the "finally" callbacks that have been registered with the pending batch.
     *
     * @return array
     */
    public function finallyCallbacks()
    {
        return $this->options['finally'] ?? [];
    }

    /**
     * Indicate that the batch should not be cancelled when a job within the batch fails.
     *
     * @param  bool  $allowFailures
     * @return $this
     */
    public function allowFailures($allowFailures = true)
    {
        $this->options['allowFailures'] = $allowFailures;

        return $this;
    }

    /**
     * Determine if the pending batch allows jobs to fail without cancelling the batch.
     *
     * @return bool
     */
    public function allowsFailures()
    {
        return Arr::get($this->options, 'allowFailures', false) === true;
    }

    /**
     * Set the name for the batch.
     *
     * @param  string  $name
     * @return $this
     */
    public function name(string $name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Specify the queue connection that the batched jobs should run on.
     *
     * @param  string  $connection
     * @return $this
     */
    public function onConnection(string $connection)
    {
        $this->options['connection'] = $connection;

        return $this;
    }

    /**
     * Get the connection used by the pending batch.
     *
     * @return string|null
     */
    public function connection()
    {
        return $this->options['connection'] ?? null;
    }

    /**
     * Specify the queue that the batched jobs should run on.
     *
     * @param  string  $queue
     * @return $this
     */
    public function onQueue(string $queue)
    {
        $this->options['queue'] = $queue;

        return $this;
    }

    /**
     * Get the queue used by the pending batch.
     *
     * @return string|null
     */
    public function queue()
    {
        return $this->options['queue'] ?? null;
    }

    /**
     * Add additional data into the batch's options array.
     *
     * @param  string  $key
     * @param  mixed  $value
     * @return $this
     */
    public function withOption(string $key, $value)
    {
        $this->options[$key] = $value;

        return $this;
    }

    /**
     * Dispatch the batch.
     *
     * @return \Illuminate\Bus\Batch
     *
     * @throws \Throwable
     */
    public function dispatch()
    {
        $repository = $this->container->make(BatchRepository::class);

        try {
            $batch = $repository->store($this);

            $batch = $batch->add($this->jobs);
        } catch (Throwable $e) {
            if (isset($batch)) {
                $repository->delete($batch->id);
            }

            throw $e;
        }

        $this->container->make(EventDispatcher::class)->dispatch(
            new BatchDispatched($batch)
        );

        return $batch;
    }

    /**
     * Dispatch the batch after the response is sent to the browser.
     *
     * @return \Illuminate\Bus\Batch
     */
    public function dispatchAfterResponse()
    {
        $repository = $this->container->make(BatchRepository::class);

        $batch = $repository->store($this);

        if ($batch) {
            $this->container->terminating(function () use ($batch) {
                $this->dispatchExistingBatch($batch);
            });
        }

        return $batch;
    }

    /**
     * Dispatch an existing batch.
     *
     * @param  \Illuminate\Bus\Batch  $batch
     * @return void
     *
     * @throws \Throwable
     */
    protected function dispatchExistingBatch($batch)
    {
        try {
            $batch = $batch->add($this->jobs);
        } catch (Throwable $e) {
            if (isset($batch)) {
                $batch->delete();
            }

            throw $e;
        }

        $this->container->make(EventDispatcher::class)->dispatch(
            new BatchDispatched($batch)
        );
    }
}