laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.52k stars 11.02k forks source link

Queued Mailable Redis: SerializesAndRestoresModelIdentifiers: ModelNotFoundException #48816

Closed stuartcusackie closed 1 year ago

stuartcusackie commented 1 year ago

Laravel Version

10.15.0

PHP Version

8.2.5

Database Driver & Version

MySQL 8

Description

I know this is has been brought up a million times before but there seems to still be a bug in queued mailables. I've been on Laracasts and various other resources and I don't see that I'm doing anything wrong.

Illuminate\Database\Eloquent\ModelNotFoundException: No query results for model [App\Models\Item]
#0 /home/forge/testapp.com/vendor/laravel/framework/src/Illuminate/Queue/SerializesAndRestoresModelIdentifiers.php(108):

I use Laravel Forge with a Redis queue managed by Horizon. There is no other special configuration. It's a simple server with the default MySQL installed.

What I'm doing is very simple. The item has been created and persisted, as shown below, but when the queued mailable job runs it cannot find the item.

public function handleItemCreation(Request $request)
{ 
  $item = Item::create([
    'name' => request('name'),
    'email' => request('email'),
  ]);

  Mail::to(request('email'))->send(new TestMailable($item));
  ...
class TestMailable extends Mailable implements ShouldQueue
{
  use Queueable, SerializesModels;

  public $item;

  public function __construct($item)
  {
    $this->item = $item;
    $this->onQueue('notifications');
  }

Retrying the job manually does work. This also happens in scheduled tasks that send queued mailables 15 minutes after the model has been persisted

Thanks.

Steps To Reproduce

  1. Set up a model (Item) and a queued mailable (TestMailable).
  2. Send the mailable and pass the recently created Item
  3. Deploy to server (forge)
  4. Create requests and watch Horizon Failed Jobs.
crynobone commented 1 year ago

Hey there, thanks for reporting this issue.

We'll need more info and/or code to debug this further. Can you please create a repository with the command below, commit the code that reproduces the issue as one separate commit on the main/master branch and share the repository here?

Please make sure that you have the latest version of the Laravel installer in order to run this command. Please also make sure you have both Git & the GitHub CLI tool properly set up.

laravel new bug-report --github="--public"

Do not amend and create a separate commit with your custom changes. After you've posted the repository, we'll try to reproduce the issue.

Thanks!

sonja-turo commented 1 year ago

What's the name of the primary key of the model? "id" is the default, and is what the queueing system looks for when trying to load the model. If you're using a different primary key name , this would cause your problem.

stuartcusackie commented 1 year ago

What's the name of the primary key of the model? "id" is the default, and is what the queueing system looks for when trying to load the model. If you're using a different primary key name , this would cause your problem.

I defined my table like so:

Schema::create('items', function (Blueprint $table) {
  $table->id();
  $table->foreignId('place_id');
  $table->foreignId('team_id');
  $table->foreignId('user_id');
  ... other string / boolean / json columns ...
  $table->timestamps();
});
stuartcusackie commented 1 year ago

Can you please create a repository with the command below, commit the code that reproduces the issue as one separate commit on the main/master branch and share the repository here?

I hope this is correct: https://github.com/stuartcusackie/laravel-bug-report-48816

I'm sorry but I'm having trouble getting Horizon Redis queues to run on my Windows machine, so I couldn't verify if the same errors are occurring. I've tested everything anyway and verified that jobs are being placed on the queue.

I made a link on the welcome page that creates a request to send a queued mailable with an object attached as described. I'm hoping that if you do this enough times then you will see some errors.

driesvints commented 1 year ago

I'm sorry but I'm having trouble getting Horizon Redis queues to run on my Windows machine

Horizon doesn't supports Windows unfortunately.

stuartcusackie commented 1 year ago

I have deployed my bug report repo to a Forge server and I cannot reproduce the error. I'm not sure what's difference there is in my real application. The failed job model has relations, but that's the only difference I can see.

I just realised something, I have a staging domain running on the same forge server. This staging domain has it's own instance of Horizon. I thought this would be fine but perhaps it is causing a conflict.

When I look at the horizon dashboard I see two horizon workers: image

I will terminate the staging horizon worker and see if my problem goes away. I think I should be using HORIZON_PREFIX in my env file when running multiple instances of horizon on the same server.

I'll come back if my issue is not resolved.

stuartcusackie commented 1 year ago

SOLUTION? I assume these errors are actually being produced by my staging codebase. The job is being placed on the same queue as the production domain and when staging tries to find the object, it does not exist in the database. The production jobs are probably being ran correctly.

I've added these to my staging env: REDIS_DB=2 REDIS_CACHE_DB=3 HORIZON_PREFIX='myapp_horizon_staging:'

I'll come back if there are still issues. Thanks for reading all of this.