2

UPDATE - This has been narrowed down to beanstalkd, sync works

I am receiving the following error when attempting to run queued commands in my production environment:

    exception 'ErrorException' with message 'unserialize(): Function spl_autoload_call() hasn't defined the class it was called for' 
in /home/forge/default/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php:74

I have tried both the beanstalkd and database drivers, no change. For simplicity, I am using the following command:

<?php namespace App\Commands;

use App\Commands\Command;

use App\User;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldBeQueued;

class TestQueueCommand extends Command implements SelfHandling, ShouldBeQueued {

    use InteractsWithQueue, SerializesModels;
    /**
     * @var User
     */
    private $user;

    /**
     * Create a new command instance.
     *
     * @param User $user
     */
    public function __construct(User $user)
    {
        //
        $this->user = $user;
    }

    /**
     * Execute the command.
     *
     * @return void
     */
    public function handle()
    {
        \Log::info("You gave me " . $this->user->fullName());
    }

}

Dispatch code:

get('queue-test', function()
{
    Bus::dispatch(new TestQueueCommand(User::first()));
});

This works in my Homestead environment, fails in production (Digital Ocean, Forge). I have several beanstalkd workers and I have tried restarting them. I have also run php artisan queue:flush.

Here is the code where the error is occurring (from source):

/**
     * Handle the queued job.
     *
     * @param  \Illuminate\Contracts\Queue\Job  $job
     * @param  array  $data
     * @return void
     */
    public function call(Job $job, array $data)
    {
        $command = $this->setJobInstanceIfNecessary(
            $job, unserialize($data['command'])
        );

        $this->dispatcher->dispatchNow($command, function($handler) use ($job)
        {
            $this->setJobInstanceIfNecessary($job, $handler);
        });

        if ( ! $job->isDeletedOrReleased())
        {
            $job->delete();
        }
    }
NightMICU
  • 9,000
  • 30
  • 89
  • 121

1 Answers1

1

In the past, I also ran into a similar issue while unserializing. The problem was the default Beanstalk job size (65,535 bytes), which might not be big enough if the class being serialized contains lots of properties that need to be kept (increasing the size of the serialized string and using more than 65K for storage).

In order to solve this, try setting the size to 131,072 or even 262,144 bytes using the -z option, on the configuration file (/etc/default/beanstalkd):

BEANSTALKD_EXTRA="-z 262144"

After that, you should restart the service.

Also note that the configuration file path might be other, depending on the distribution you're using.

And since you're using Digital Ocean, you might find their documentation useful.

Quetzy Garcia
  • 1,820
  • 1
  • 21
  • 23
  • Kind of went over my head on this. Even the simplest of tasks being completed in a Command, such as writing "Hello World" to the log, failed in the same way. Nothing super complicated going on with lots of properties. – NightMICU Apr 18 '15 at 16:48
  • But have you at least tried increasing the job size to see if it works? There's also a note in the [documentation](http://laravel.com/docs/5.0/queues#queueing-closures) about these kind of issues: **Instead of making objects available to queued Closures via the use directive, consider passing primary keys and re-pulling the associated models from within your queue job. This often avoids unexpected serialization behavior.** – Quetzy Garcia Apr 18 '15 at 16:57
  • Ahh now that is interesting. I'm using Iron now but I've had issues in the past with runaway jobs, so I was hoping to keep everything on Beantsalk. I'll poke around and report back when I have time. Do I just run `beanstalkd -z 26144` in terminal? – NightMICU Apr 18 '15 at 16:59
  • You'll just have to edit the configuration file for Beanstalk and restart the service. See my updated response. – Quetzy Garcia Apr 18 '15 at 17:08