Giter Site home page Giter Site logo

laravel-sqs-fifo-queue's Introduction

laravel-sqs-fifo-queue

Latest Version on Packagist Software License Build Status Coverage Status Quality Score Total Downloads

This Laravel/Lumen package provides a queue driver for Amazon's SQS FIFO queues. While Laravel works with Amazon's SQS standard queues out of the box, FIFO queues are slightly different and are not handled properly by Laravel. That is where this package comes in.

Versions

This package has been tested on Laravel 4.1 through Laravel 10.x, though it may continue to work on later versions as they are released. This section will be updated to reflect the versions on which the package has actually been tested.

This readme has been updated to show information for the most currently supported versions (9.x - 10.x). For Laravel 4.1 through Laravel 8.x, view the 2.x branch.

Install

Via Composer

$ composer require shiftonelabs/laravel-sqs-fifo-queue

Once composer has been updated and the package has been installed, the service provider will need to be loaded.

Laravel 9.x, 10.x

This package uses auto package discovery. The service provider will automatically be registered.

Lumen 9.x, 10.x

Open bootstrap/app.php and add following line under the "Register Service Providers" section:

$app->register(ShiftOneLabs\LaravelSqsFifoQueue\LaravelSqsFifoQueueServiceProvider::class);

Configuration

Laravel/Lumen 9.x, 10.x

If using Lumen, create a config directory in your project root if you don't already have one. Next, copy vendor/laravel/lumen-framework/config/queue.php to config/queue.php.

Now, for both Laravel and Lumen, open config/queue.php and add the following entry to the connections array.

'sqs-fifo' => [
    'driver' => 'sqs-fifo',
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
    'prefix' => env('SQS_FIFO_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
    'queue' => env('SQS_FIFO_QUEUE', 'default.fifo'),
    'suffix' => env('SQS_FIFO_SUFFIX'),
    'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
    'after_commit' => false,
    'group' => 'default',
    'deduplicator' => env('SQS_FIFO_DEDUPLICATOR', 'unique'),
    'allow_delay' => env('SQS_FIFO_ALLOW_DELAY', false),
],

Example .env file:

AWS_ACCESS_KEY_ID=ABCDEFGHIJKLMNOPQRST
AWS_SECRET_ACCESS_KEY=1a23bc/deFgHijKl4mNOp5qrS6TUVwXyz7ABCDef
SQS_FIFO_PREFIX=https://sqs.us-east-1.amazonaws.com/123456789012
SQS_FIFO_QUEUE=queuename.fifo
SQS_FIFO_SUFFIX=-staging
AWS_DEFAULT_REGION=us-east-1
SQS_FIFO_DEDUPLICATOR=unique
SQS_FIFO_ALLOW_DELAY=false

If you'd like this to be the default connection, also set QUEUE_CONNECTION=sqs-fifo in the .env file.

Capsule

If using the illuminate\queue component Capsule outside of Lumen/Laravel:

use Illuminate\Queue\Capsule\Manager as Queue;
use ShiftOneLabs\LaravelSqsFifoQueue\LaravelSqsFifoQueueServiceProvider;

$queue = new Queue;

$queue->addConnection([
    'driver' => 'sqs-fifo',
    'key'    => 'your-public-key',   // ex: ABCDEFGHIJKLMNOPQRST
    'secret' => 'your-secret-key',   // ex: 1a23bc/deFgHijKl4mNOp5qrS6TUVwXyz7ABCDef
    'prefix' => 'your-prefix',       // ex: https://sqs.us-east-1.amazonaws.com/your-account-id
    'queue' => 'your-queue-name',    // ex: queuename.fifo
    'suffix' => 'your-suffix',       // ex: -staging
    'region' => 'your-queue-region', // ex: us-east-1
    'after_commit' => false,
    'group' => 'default',
    'deduplicator' => 'unique',
    'allow_delay' => false,
], 'sqs-fifo');

// Make this Capsule instance available globally via static methods... (optional)
$queue->setAsGlobal();

// Register the 'queue' alias in the Container, then register the SQS FIFO provider.
$app = $queue->getContainer();
$app->instance('queue', $queue->getQueueManager());
(new LaravelSqsFifoQueueServiceProvider($app))->register();

Credentials

The key and secret config options may be omitted if using one of the alternative options for providing AWS credentials (e.g. using an AWS credentials file). More information about alternative options is available in the AWS PHP SDK guide here.

AWS STS Session Token

The 'token' => env('AWS_SESSION_TOKEN'), config option may be added if you need to specify an AWS STS temporary session token in the config. This is needed for some specific environments, such as AWS Lambda.

Queue Suffix

The suffix config option is used to support queues for different environments without having to specify the environment suffix when using the queue. For example, if you have an emails-staging.fifo queue and an emails-production.fifo queue, you can set the suffix config to -staging or -production based on the environment, and your code can continue to use emails.fifo without needing to know the environment. So, Job::dispatch()->onQueue('emails.fifo') will use either the emails-staging.fifo or the emails-production.fifo queue, depending on the suffix defined in the config.

NB: SQS FIFO queues must end with a .fifo suffix. As seen in the example above, any suffix defined in the config will come before the required .fifo suffix. Do not specify .fifo in the suffix config or the queue name will not generate correctly.

Jobs & Database Transactions

The after_commit configuration option is used to govern how jobs are handled when queued in the middle of a database transaction. When set to true, this option ensures that jobs that are queued during a database transaction are not actually dispatched until after the database transaction is committed. If the transaction is rolled back, the job will be discarded and not dispatched. If there are no active database transactions, the job will be dispatched immediately.

Queued Event Listeners

At this time, queued event listeners cannot be handled by this package. The implementation for this would require taking over Laravel's event dispatcher, which is not something this package is prepared to do at this time. To work around this, you would need to convert your queued listener to not be queued, but to then dispatch a new queued job that handles the work.

Usage

For the most part, usage of this queue driver is the same as the built in queue drivers. There are, however, a few extra things to consider when working with Amazon's SQS FIFO queues.

Message Groups

In addition to being able to have multiple queue names for each connection, an SQS FIFO queue also allows one to have multiple "message groups" for each FIFO queue. These message groups are used to group related jobs together, and jobs are processed in FIFO order per group. This is important, as your queue performance may depend on being able to assign message groups properly. If you have 100 jobs in the queue, and they all belong to one message group, then only one queue worker will be able to process the jobs at a time. If, however, they can logically be split across 5 message groups, then you could have 5 queue workers processing the jobs from the queues (one per group). The FIFO ordering is per message group.

Currently, by default, all queued jobs will be lumped into one group, as defined in the configuration file. In the configuration provided above, all queued jobs would be sent as part of the default group. The group can be changed per job using the onMessageGroup() method, which will be explained more below.

The group id must not be empty, must not be more than 128 characters, and can contain alphanumeric characters and punctuation (!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~).

In a future release, the message group will be able to be assigned to a function, like the deduplicator below.

Deduplication

When sending jobs to the SQS FIFO queue, Amazon requires a way to determine if the job is a duplicate of a job already in the queue. SQS FIFO queues have a 5 minute deduplication interval, meaning that if a duplicate message is sent within the interval, it will be accepted successfully (no errors), but it will not be delivered or processed.

Determining duplicate messages is generally handled in one of two ways: either all messages are considered unique regardless of content, or messages are considered duplicates if they have the same content.

This package handles deduplication via the deduplicator configuration option.

To have all messages considered unique, set the deduplicator to unique.

To have messages with the same content considered duplicates, there are two options, depending on how the FIFO queue has been configured. If the FIFO queue has been setup in Amazon with the Content-Based Deduplication feature enabled, then the deduplicator should be set to sqs. This tells the connection to rely on Amazon to determine content uniqueness. However, if the Content-Based Deduplication feature is disabled, the deduplicator should be set to content. Note, if Content-Based Deduplication is disabled, and the deduplicator is set to sqs, this will generate an error when attempting to send a job to the queue.

To summarize:

  • sqs - This is used when messages with the same content should be considered duplicates and Content-Based Deduplication is enabled on the SQS FIFO queue.
  • content - This is used when messages with the same content should be considered duplicates but Content-Based Deduplication is disabled on the SQS FIFO queue.
  • unique - This is used when all messages should be considered unique, regardless of content.

If there is a need for a different deduplication algorithm, custom deduplication methods can be registered in the container.

Finally, by default, all queued jobs will use the deduplicator defined in the configuration file. This can be changed per job using the withDeduplicator() method.

Delayed Jobs

SQS FIFO queues do not support per-message delays, only per-queue delays. The desired delay is defined on the queue itself when the queue is setup in the Amazon Console. Attempting to set a delay on a job sent to a FIFO queue will have no effect. In order to delay a job, you can push() the job to an SQS FIFO queue that has been defined with a delivery delay.

Since per-message delays are not supported, using the later() method to push a job to an SQS FIFO queue will throw a BadMethodCallException exception by default. However, this behavior can be changed using the allow_delay config option.

Setting the allow_delay config option to true for a queue will allow the later() method to push a job on that queue without an exception. However, the delay parameter sent to the later() method is completely ignored since the delay time is defined in SQS on the queue itself.

Advanced Usage

Per-Job Group and Deduplicator

If you need to change the group or the deduplicator for a specific job, you will need access to the onMessageGroup() and withDeduplicator() methods. These methods are provided through the ShiftOneLabs\LaravelSqsFifoQueue\Bus\SqsFifoQueueable trait. Once you add this trait to your job class, you can change the group and/or the deduplicator for that specific job without affecting any other jobs on the queue.

Code Example

Job:

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use ShiftOneLabs\LaravelSqsFifoQueue\Bus\SqsFifoQueueable;

class ProcessCoin implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SqsFifoQueueable, SerializesModels;

    //
}

Usage:

dispatch(
    (new \App\Jobs\ProcessCoin())
        ->onMessageGroup('quarter')
        ->withDeduplicator('unique')
);

Notification:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use ShiftOneLabs\LaravelSqsFifoQueue\Bus\SqsFifoQueueable;

class InvoicePaid extends Notification implements ShouldQueue
{
    use Queueable, SqsFifoQueueable;

    //
}

Usage:

$user->notify(
    (new InvoicePaid($invoice))->onMessageGroup($invoice->id)
);

Mailable:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;
use ShiftOneLabs\LaravelSqsFifoQueue\Bus\SqsFifoQueueable;

class OrderShipped extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels, SqsFifoQueueable;

    //
}

Usage:

Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->queue(new OrderShipped($order)->onMessageGroup($order->number));

Custom Deduplicator

The deduplicators work by generating a deduplication id that is sent to the queue. If two messages generate the same deduplication id, the second message is considered a duplicate, and the message will not be delivered if it is within the 5 minute deduplication interval.

If you have some custom logic that needs to be used to generate the deduplication id, you can register your own custom deduplicator. The deduplicators are stored in the IoC container with the prefix queue.sqs-fifo.deduplicator. So, for example, the unique deduplicator is aliased to queue.sqs-fifo.deduplicator.unique.

Custom deduplicators are created by registering a new prefixed alias in the IoC. This alias should resolve to a new object instance that implements the ShiftOneLabs\LaravelSqsFifoQueue\Contracts\Queue\Deduplicator contract. You can either define a new class that implements this contract, or you can create a new ShiftOneLabs\LaravelSqsFifoQueue\Queue\Deduplicators\Callback instance, which takes a Closure that performs the deduplication logic. The defined Closure should take two parameters: $payload and $queue, where $payload is the json_encoded() message to send to the queue, and $queue is the name of the queue to which the message is being sent. The generated id must not be more than 128 characters, and can contain alphanumeric characters and punctuation (!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~).

So, for example, if you wanted to create a random deduplicator that would randomly select some jobs to be duplicates, you could add the following line in the register() method of your AppServiceProvider:

$this->app->bind('queue.sqs-fifo.deduplicator.random', function ($app) {
    return new \ShiftOneLabs\LaravelSqsFifoQueue\Queue\Deduplicators\Callback(function ($payload, $queue) {
        // Return the deduplication id generated for messages. Randomly 0 or 1.
        return mt_rand(0,1);
    });
}

Or, if you prefer to create a new class, your class would look like this:

namespace App\Deduplicators;

use ShiftOneLabs\LaravelSqsFifoQueue\Contracts\Queue\Deduplicator;

class Random implements Deduplicator
{
    public function generate($payload, $queue)
    {
        // Return the deduplication id generated for messages. Randomly 0 or 1.
        return mt_rand(0,1);
    }
}

And you could register that class in your AppServiceProvider like this:

$this->app->bind('queue.sqs-fifo.deduplicator.random', App\Deduplicators\Random::class);

With this alias registered, you could update the deduplicator key in your configuration to use the value random, or you could set the deduplicator on individual jobs by calling withDeduplicator('random') on the job.

Contributing

Contributions are welcome. Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.

laravel-sqs-fifo-queue's People

Contributors

glaubersatiro avatar patrickcarlohickman avatar powellblyth avatar utkuyildirim avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-sqs-fifo-queue's Issues

Cannot use integer as messageGroupId anymore

After upgrading from Laravel 8 to Laravel 9 we upgraded to your latest version but now all the places where we used an integer as messageGroupId are failing.

In QueryCompatibleInputMiddleware.php line 165:

  The provided type for `MessageGroupId` value was `integer`. The modeled type is `string`.

Should public function onMessageGroup($messageGroupId) only accept strings (or cast inputs into string)?

Thank you

"Substring must be compatible" issue

Declaration of ShiftOneLabs\LaravelSqsFifoQueue\Support\Str::substr($string, $start, $length = null) must be compatible with Illuminate\Support\Str::substr($string, $start, $length = null, $encoding = 'UTF-8') {"userId":1,"exception":"[object] (Symfony\Component\ErrorHandler\Error\FatalError(code: 0): Declaration of ShiftOneLabs\LaravelSqsFifoQueue\Support\Str::substr($string, $start, $length = null) must be compatible with Illuminate\Support\Str::substr($string, $start, $length = null, $encoding = 'UTF-8') at /Users/drew/product/vendor/shiftonelabs/laravel-sqs-fifo-queue/src/Support/Str.php:47)

I was able to fix the error by adding encode as a param to this function in the str.php file

/**
     * Returns the portion of string specified by the start and length parameters.
     *
     * The substr method wasn't added to the Str class until Laravel 5.1.
     * Add the implementation here to support older versions of Laravel.
     *
     * @param  string  $string
     * @param  int  $start
     * @param  int|null  $length
     *
     * @return string
     */
    public static function substr($string, $start, $length = null, $encoding = 'UTF-8')
    {
        return mb_substr($string, $start, $length, $encoding);
    }

That being said, I know it's not a real fix. I'm a fairly new developer, can someone help me figure out what this solution is?

Incompatible with Illuminate\Support\Str::substr()

Hello, By any chance, did anyone encounter this error below when trying to send a message to AWS SQS Queue?

Environment

  • Laravel 9
  • PHP 8

Code

  • From Controller:
    • CreateSqsTaskJob::dispatch()->onConnection('sqs-fifo');
  • Code for CreateSqsTaskJob class
class CreateSqsTaskJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    // protected $data;

    public function __construct()
    {
        //
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //
    }
}
  • queue.php connection
'sqs-fifo' => [
            'driver' => 'sqs-fifo',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'queue' => env('SQS_QUEUE'),
            'region' => env('AWS_DEFAULT_REGION'),
            'group' => 'default',
            'deduplicator' => 'unique',
            'queue_url' => env('SQS_QUEUE_URL'),
        ],

Error

ShiftOneLabs\LaravelSqsFifoQueue\Support\Str::substr()' is not compatible with method 'Illuminate\Support\Str::substr()

Inconsistent Message Group Ids

Hello and thank you for your efforts on this package! It's much appreciated.

I'm working in Laravel 8 on Vapor and am having some trouble getting the queued notifications to use different message group ids. I'm queueing notifications using the following as an example:

(new ReadyNotification($assignment))
    ->onConnection('fifo')
    ->onMessageGroup($assignment->getUuid())

My queue configuration looks like this:

'fifo' => [
    'driver' => 'sqs-fifo',
    'key' => env('SQS_KEY'),
    'secret' => env('SQS_SECRET'),
    'prefix' => env('SQS_PREFIX'),
    'suffix' => env('SQS_SUFFIX', '-develop'),
    'queue' => 'fifo.fifo',
    'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
    'group' => 'fifo',
    'deduplicator' => 'sqs',
    'allow_delay' => env('SQS_ALLOW_DELAY'),
],

As I've inspected jobs on the queue occasionally one will be on the {assignmentUuid} group but they are typically falling onto the default group as specified by the config above.

I've attempted to set the message group in the constructor of the notification but it results in the same inconsistent behavior.

What advice might you have as I continue to debug this?

Again, thank you for your time!

sqs-fifo with jobs and delays

I'm not sure if this is a question specific to your Laravel implementation (great work btw) or whether its a SQS FIFO specific thing, but if I create a job with a delay as per the Laravel docs:

ProcessPodcast::dispatch($podcast)
    ->delay(now()->addMinutes(10));

Does that means other jobs (without a delay) sent to the queue will be processed before this one, even though they arrived after?

I guess the question could be rephrased to: can I control the order of FIFO items, by setting the delay?

When does this oss test Laravel 9?

Thank you for your great project. Laravel9 was released February 8th, 2022. So, we plan to use Laravel 9 as a web application in our project. And I have a question. Does this oss have plans to test Larave9? I want to know a rough roadmap on it for me and other developers waiting for that.

Also, I will share the information on our local testing result with Laravel9 if I get it.

Error in use Queue::connection('sqs-fifo')

I want to trigger a pushRaw, for that I'm using the following:
Queue::connection('sqs-fifo')->pushRaw($myData);

however, the following error is reported:

In LaravelSqsFifoQueueServiceProvider.php line 71: Call to undefined method Illuminate \ Support \ Facades \ Queue :: extend ()

I'm use Laravel 5.6

Are Queued Event Listeners not fully supported?

I have an event with one of its listeners implementing ShouldQueue with connection set to sqs-fifo like this:

class MyEventListener implements ShouldQueue
{
    public $connection = 'sqs-fifo';

    public function handle($event)
    {
        logger()->debug('queued event listener handled');
    }
}

This works fine. However, I don't seem to be able to specify the Message Group ID. I have tried the following:

  1. use SqsFifoQueueable;-trait and call $this->onMessageGroup('custom-group'); in the listener __construct()
  2. Specify $messageGroupId property manually: public $messageGroupId = 'custom-group';

Both messages sent to my SQS FIFO queue have default Message Group ID, not custom-group as I had hoped.

Am I missing something? Or is using Queued Event Listeners simply not supported (yet)?

No way to set token via config

Hello, notice this issue when updated to latest AWS SDK version

Environment

Laravel 9
PHP 8.2
AWS SDK: 3.273.0

AWS config example

        'sqs-fifo' => [
            'driver' => 'sqs-fifo',
            'key' => env('AWS_ACCESS_KEY'),
            'secret' => env('AWS_SECRET_KEY'),
            'token' => env('AWS_SESSION_TOKEN'),
            'prefix' => env('SQS_PREFIX'),
            'suffix' => null,
            'queue' => 'second_lane.fifo',
            'region' => 'us-west-2',
            'group' => 'default',
            'deduplicator' => 'unique',
            'allow_delay' => null,
        ],

Code

return new SqsFifoQueue(
            new SqsClient(
                Arr::except($config, ['token'])
            ),
            $config['queue'],
            $config['prefix'] ?? '',
            $config['suffix'] ?? '',
            (bool)($config['after_commit'] ?? null),
            $group,
            $deduplicator,
            $allowDelay
        );

Problem

AWS SDK require Token to be provided.
When no Token provided to AwsClient it uses \Aws\Token\TokenProvider::defaultProvider.
It can look for token using some default methods but in some case it could find token somehow as string and fail with error:

Invalid configuration value provided for "token". Expected Aws\Token\TokenInterface|Aws\CacheInterface|array|bool|callable, but got string(488) "...." token: (Aws\Token\TokenInterface|Aws\CacheInterface|array|bool|callable) Specifies the token used to authorize requests. Provide an Aws\Token\TokenInterface object, an associative array of "token", and an optional "expiration" key, false to use a null token, or a callable token provider used to fetch a token or return null. See Aws\Token\TokenProvider for a list of built-in credentials providers. If no token is provided, the SDK will attempt to load one from the environment.

Because there no way for me to find from where it's coming there also no way to set it manually using config and fix the problem using codebase.

Possible Solution

Make token setable form the config:
When token present on top level config use it not only for token field in credentials but also for token array itself

FATAL ERROR - Symfony\Component\ErrorHandler\Error\FatalError

Laravel version: 9.44.0
PHP version: 8.1

Declaration of ShiftOneLabs\LaravelSqsFifoQueue\Support\Str::substr($string, $start, $length = null) must be compatible with Illuminate\Support\Str::substr($string, $start, $length = null, $encoding = 'UTF-8')

It looks like this is a major issue, because it breaks queue workers.

I think extending Illuminate\Support\Str is no more necessary.

Thank you

PHP worker fails to run queue items in laravel 4.2

Hi, I'm trying to integrate this packege with laravel 4.2. The problem I'm having is that laravel 4.2 stores the jobs class under the "job" key and from that a new instance is created and so on.

In my case I need different message groups for each job, so I am giving an instance of the job to the queue and setting $messageGroupId for it, but doing so under the "job" the name of the class in not sent.

Expected message sent to sqs fifo
{"job":"App\\Models\\Jobs\\AJob","data":[],"group":"group-1"}
Actual message is sent to sqs fifo
{"job":{"messageGroupId":"events-1","deduplicator":null},"data":[],"group":"group-1"}

Target class [XXX] does not exist of message from AWS SQS Queue

When Laravel process queue, not resolve class from SQS message.

The SQS message is:
JSON { "uuid":"1234", "displayName":"offer_status_changed", "job":"offer_status_changed", ... "data":{ "id":71, ... } }

The job name not include class namespace and Laravel throw errors:

  • Target class [offer_status_changed] does not exist
  • [object] (ReflectionException(code: -1): Class \"offer_status_changed\" does not exist

I understand that job should include namespace with method "job":"App\\Jobs\\offer_status_changed@handle",

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.