filamentphp / filament

A collection of beautiful full-stack components for Laravel. The perfect starting point for your next app. Using Livewire, Alpine.js and Tailwind CSS.
https://filamentphp.com
MIT License
19.14k stars 2.95k forks source link

Fail to import ~not so~ big file using default `ImportAction` #10651

Closed tembra closed 10 months ago

tembra commented 10 months ago

Package

filament/filament

Package Version

v3.1.31

Laravel Version

v10.39.0

Livewire Version

v3.3.3

PHP Version

PHP 8.2.14

Problem description

When use ImportAction to import a file with 2k rows I got max execution time of 30 seconds exceed followed by 419 Page Expired, not always in the same order.

The import button remains with the loading animation until I got the errors.

I can only achieve success when I import about 500 rows at max.

https://github.com/filamentphp/filament/assets/6340360/7d445de9-423b-47bf-b8a5-0e3946b3c07b

Expected behavior

After the file has been uploaded and columns mapped and then clicked the import button, the entire process should be executed on background.

Steps to reproduce

  1. Clone the repository and enter the folder
git clone https://github.com/tembra/filament-import-action-error.git && cd filament-import-action-error/
  1. Create a PostgreSQL database named filament_import_action_error
  2. Create .env file
cp .env.example .env
  1. Change .env file for your needs (mainly database)
  2. Install dependencies
composer install
  1. Generate an application key
php artisan key:generate
  1. Run migrations
php artisan migrate
  1. Create a filament user
php artisan make:filament-user
  1. Start the application

    php artisan serve
  2. If everything is ok, when visiting the app URL you should view the Laravel welcome page.

  3. Visit the route /generate-import-file to generate a random 2k rows CSV file that will be imported later. The file should be downloaded.

  4. Visit the route /admin to access the Filament panel and log in with the created user.

  5. Access the Users resource and import the generated file.

  6. After a while the errors will be shown.

For my case the big file is about 2k rows but it seems that over 500 rows is enough to raise the errors.

Reproduction repository

https://github.com/tembra/filament-import-action-error

Relevant log output

No response

github-actions[bot] commented 10 months ago

Hey @tembra! We're sorry to hear that you've hit this issue. 💛

However, it looks like you forgot to fill in the reproduction repository URL. Can you edit your original post and then we'll look at your issue?

We need a public GitHub repository which contains a Laravel app with the minimal amount of Filament code to reproduce the problem. Please do not link to your actual project, what we need instead is a minimal reproduction in a fresh project without any unnecessary code. This means it doesn't matter if your real project is private / confidential, since we want a link to a separate, isolated reproduction. That would allow us to download it and review your bug much easier, so it can be fixed quicker. Please make sure to include a database seeder with everything we need to set the app up quickly.

github-actions[bot] commented 10 months ago

Thank you for providing reproduction steps! Reopening the issue now.

tembra commented 10 months ago

More information

While writing another importer and testing/debuging it I used dd($var) inside the beforeSave hook to inspect the content of a variable.

After the debug is shown I got the error 419 Page Expired and get logged out of the panel.

It seems that this HTTP error is related with a script execution being abrupt interrupted during the import process.

Initially I thought that it could occur by an unhandled exception too. However after change the dd by throw new \Exception the HTTP error is not shown and I stay logged in.

tembra commented 10 months ago

Solution

My problem was that I forgot to set the Laravel queue connection driver on .env (QUEUE_CONNECTION).

It was configured with the default driver that is sync. From Laravel documentation:

In new Laravel applications, the sync driver is the default queue driver. This driver executes jobs synchronously in the foreground of the current request, which is often convenient during local development.

After setting the driver to database solve the problem for me (QUEUE_CONNECTION=database).

For anyone that could check this issue later, if you decide to use database connection driver, you will also need to run php artisan queue:table and php artisan migrate to generate the migration and create the jobs table into your database.

However you may have other needs and it's valuable to see other options of connections in the Laravel documentation.

Finally, do not forget to run php artisan queue:work -v in a separate terminal window to let Laravel watching and processing the jobs with verbose (optional), independently of the connection you chose. Again, see Laravel documentation for more options/informations.

What do you think to add theses informations as a notice on import action documentation?


Question

After all I'm still curious about the 419 Page Expired HTTP code I've got.

danharrin commented 10 months ago

Closing as you have done the investigation and it's related to using the sync queue driver. While it is not strictly necessary to use a separate queue worker, like everything that is queued in Laravel it will perform better if you do.

naseef commented 7 months ago

I am facing the same issue . 419 page expired when uploading bigger file

@danharrin is this intended for the sync driver?

danharrin commented 7 months ago

The sync driver should only be used for testing as it is not a real queue driver that is able to handle long processes, it defeats the point of having a queue in the first place if you use it everywhere