Framework: Queue Job Error: Serialization of 'Closure' is not allowed when calling another Job

Created on 28 Sep 2017  路  1Comment  路  Source: laravel/framework

  • Laravel Version: 5.5.4
  • PHP Version: 7.1
  • Database Driver & Version: Postgres 9.6.3

Description:

I want a job A to dispatch another job B, where job B will be validating data from the database in chunks.
Job A

    /**
     * Handle the event.
     *
     * @param BatchPersisted $event
     * @return void
     */
    public function handle(BatchPersisted $event)
    {
        if ($this->attempts() > 1) {
            logger('Validation Job Failed!');
            $this->fail();
        }
        $batch = $event->getBatch();

        $batch->updateStatus(Batch::STATUS_VALIDATING);

        logger('Batch Uploaded Listened: Now Validating');
        foreach (Batch::$ENTITIES_NAME as $entity_name => $entity_class_name) {
//            $this->validateEntity($entity_class_name, $batch, $entity_name);
            dispatch(new EntityValidationJob($batch));
        }
        event(new BatchValidated($batch));
    }

then Job B

<?php

namespace App\Jobs;

use App\Batch;
use App\Instalment;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class EntityValidationJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $validator;
    /**
     * @var Batch
     */
    private $batch;
    /**
     * @var
     */
    private $entity;

    /**
     * Create a new job instance.
     *
     * @param Batch $batch
     * @param string $entity
     */
    public function __construct(Batch $batch, $entity = 'LoanRelation')
    {
        $this->validator = app('validator');
        $this->batch = $batch;
        $this->entity = $entity;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $entity_class_name = Batch::$ENTITIES_NAME[$this->entity];

        /** @var Builder $model */
        $raw_model = app($entity_class_name);
        $model = call_user_func_array([$raw_model, 'whereBatchId'], [$this->batch->id]);
        $total = $model->count();
        $generator = $model->cursor();
        $error_count = 0;

        /** @var Instalment $item */
        foreach ($generator as $item) {
            $validator = $this->validator->make($item->toArray(), $raw_model::rules());
            // The respective loan / customer code ..
            $code = $item->detectIfLoanOrCustomerCode();
            //  if a record/row passes, update pass column to true
            //  if it fails, update error table with id, code (customer/loan), errors (in json)
            if ($validator->fails()) {

                $item->errata()->delete();

                $item->errata()->create([
                    'code' => ($code) ? $code : 'Not Provided',
                    'entity' => $this->entity,
                    'batch_id' => ($this->batch)->id,
                    'errors' => $validator->errors()->toJson(),
                ]);

                $item->update(['pass' => 0]);

                $error_count++;
            } else {
                // Update the row as pass!
                $item->update(['pass' => 1]);
                // TODO Go through every entity that needs to validate presence in the parent file.
                // TRY THIS MF!
                $item->validatingDependencies();

            }
            // log the progress of the app
            logger(class_basename($item) . ' ...: ' . ($generator->key() + 1) . '/' . $total . " (Errors: $error_count)");
        }
        // log the progress of the file name
        logger("Validated:- Batch name: {$this->batch->name} Entity Name: {$raw_model->getTable()}");
    }
}

This produce the below error.

 Serialization of 'Closure' is not allowed {"exception":"[object] (Exception(code: 0): Serialization of 'Closure' is not allowed at /Users/leyluj/projects/akili_works/mikopo/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:128)

Most helpful comment

Don't do $this->validator = app('validator');, laravel will try to serialize all job class properties, this will cause many issues, one important con also is a bigger job payload which sqs will compain about for example.

>All comments

Don't do $this->validator = app('validator');, laravel will try to serialize all job class properties, this will cause many issues, one important con also is a bigger job payload which sqs will compain about for example.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sebastianbergmann picture sebastianbergmann  路  93Comments

Xerotherm1c picture Xerotherm1c  路  70Comments

ThomHurks picture ThomHurks  路  75Comments

mnpenner picture mnpenner  路  72Comments

astr0naugh7 picture astr0naugh7  路  65Comments