Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Octane file upload issue #3733

Open
uvarats opened this issue Nov 27, 2024 · 0 comments
Open

Octane file upload issue #3733

uvarats opened this issue Nov 27, 2024 · 0 comments

Comments

@uvarats
Copy link

uvarats commented Nov 27, 2024

I am using spatie/laravel-medialibrary for model files upload and Octane + RoadRunner as a server. Files are uploaded via the Backpack admin panel (i dont think, that this is really important).

I faced some issue, when uploading image for new model (when model does not exists in db). After several model creates with file upload, there is error, that looks like:

Stacktrace[2024-11-27 15:43:31] local.ERROR: fopen(/app/storage/app/public/backpack/temp/1480184708144619212-ZIxE.jpg): Failed to open stream: No such file or directory {"exception":"[object] (ErrorException(code: 0): fopen(/app/storage/app/public/backpack/temp/1480184708144619212-ZIxE.jpg): Failed to open stream: No such file or directory at /app/vendor/spatie/laravel-medialibrary/src/MediaCollections/Filesystem.php:138)
[stacktrace]
#0 /app/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(256): Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'fopen(/app/stor...', '/app/vendor/spa...', 138)
#1 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->Illuminate\Foundation\Bootstrap\{closure}(2, 'fopen(/app/stor...', '/app/vendor/spa...', 138)
#2 /app/vendor/spatie/laravel-medialibrary/src/MediaCollections/Filesystem.php(138): fopen('/app/storage/ap...', 'r')
#3 /app/vendor/spatie/laravel-medialibrary/src/MediaCollections/Filesystem.php(29): Spatie\MediaLibrary\MediaCollections\Filesystem->copyToMediaLibrary('/app/storage/ap...', Object(App\Models\Media), NULL, '148018470814461...')
#4 /app/vendor/spatie/laravel-medialibrary/src/MediaCollections/FileAdder.php(470): Spatie\MediaLibrary\MediaCollections\Filesystem->add('/app/storage/ap...', Object(App\Models\Media), '148018470814461...')
#5 /app/vendor/spatie/laravel-medialibrary/src/MediaCollections/FileAdder.php(439): Spatie\MediaLibrary\MediaCollections\FileAdder->processMediaItem(Object(App\Backpack\Models\Catalog\CatalogPaperCatalogue), Object(App\Models\Media), Object(Spatie\MediaLibrary\MediaCollections\FileAdder))
#6 /app/vendor/spatie/laravel-medialibrary/src/InteractsWithMedia.php(559): Spatie\MediaLibrary\MediaCollections\FileAdder->Spatie\MediaLibrary\MediaCollections\{closure}(Object(App\Models\Media), Object(Spatie\MediaLibrary\MediaCollections\FileAdder))
#7 /app/vendor/spatie/laravel-medialibrary/src/MediaCollections/FileAdder.php(438): App\Backpack\Models\Catalog\CatalogPaperCatalogue->processUnattachedMedia(Object(Closure))
#8 /app/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(458): Spatie\MediaLibrary\MediaCollections\FileAdder->Spatie\MediaLibrary\MediaCollections\{closure}(Object(App\Backpack\Models\Catalog\CatalogPaperCatalogue))
#9 /app/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(286): Illuminate\Events\Dispatcher->Illuminate\Events\{closure}('eloquent.create...', Array)
#10 /app/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(266): Illuminate\Events\Dispatcher->invokeListeners('eloquent.create...', Array, false)
#11 /app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php(215): Illuminate\Events\Dispatcher->dispatch('eloquent.create...', Array)
#12 /app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1344): Illuminate\Database\Eloquent\Model->fireModelEvent('created', false)
#13 /app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1162): Illuminate\Database\Eloquent\Model->performInsert(Object(Illuminate\Database\Eloquent\Builder))
#14 /app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(1079): Illuminate\Database\Eloquent\Model->save()
#15 /app/vendor/laravel/framework/src/Illuminate/Support/helpers.php(380): Illuminate\Database\Eloquent\Builder->Illuminate\Database\Eloquent\{closure}(Object(App\Backpack\Models\Catalog\CatalogPaperCatalogue))
#16 /app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(1078): tap(Object(App\Backpack\Models\Catalog\CatalogPaperCatalogue), Object(Closure))
#17 /app/vendor/laravel/framework/src/Illuminate/Support/Traits/ForwardsCalls.php(23): Illuminate\Database\Eloquent\Builder->create(Array)
#18 /app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2367): Illuminate\Database\Eloquent\Model->forwardCallTo(Object(Illuminate\Database\Eloquent\Builder), 'create', Array)
#19 /app/vendor/backpack/crud/src/app/Library/CrudPanel/Traits/Create.php(39): Illuminate\Database\Eloquent\Model->__call('create', Array)
#20 /app/vendor/backpack/crud/src/app/Library/CrudPanel/Traits/Create.php(31): Backpack\CRUD\app\Library\CrudPanel\CrudPanel->createModelAndRelations(Array, Array)
#21 /app/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php(30): Backpack\CRUD\app\Library\CrudPanel\CrudPanel->Backpack\CRUD\app\Library\CrudPanel\Traits\{closure}(Object(Illuminate\Database\PostgresConnection))
#22 /app/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(456): Illuminate\Database\Connection->transaction(Object(Closure))
#23 /app/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(358): Illuminate\Database\DatabaseManager->__call('transaction', Array)
#24 /app/vendor/backpack/crud/src/app/Library/CrudPanel/Traits/Create.php(31): Illuminate\Support\Facades\Facade::__callStatic('transaction', Array)
#25 /app/app/Backpack/Http/Controllers/Catalog/CatalogPaperCatalogueCrudController.php(54): Backpack\CRUD\app\Library\CrudPanel\CrudPanel->create(Array)
#26 /app/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): App\Backpack\Http\Controllers\Catalog\CatalogPaperCatalogueCrudController->store()
#27 /app/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(43): Illuminate\Routing\Controller->callAction('store', Array)
#28 /app/vendor/laravel/framework/src/Illuminate/Routing/Route.php(264): Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route), Object(App\Backpack\Http\Controllers\Catalog\CatalogPaperCatalogueCrudController), 'store')
#29 /app/vendor/laravel/framework/src/Illuminate/Routing/Route.php(210): Illuminate\Routing\Route->runController()
#30 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(808): Illuminate\Routing\Route->run()
#31 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\Routing\Router->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#32 /app/app/Backpack/Http/Controllers/BaseController.php(52): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#33 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(165): App\Backpack\Http\Controllers\BaseController->App\Backpack\Http\Controllers\{closure}(Object(Illuminate\Http\Request), Object(Closure))
#34 /app/vendor/backpack/language-switcher/src/Http/Middleware/LanguageSwitcherMiddleware.php(38): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#35 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Backpack\LanguageSwitcher\Http\Middleware\LanguageSwitcherMiddleware->handle(Object(Illuminate\Http\Request), Object(Closure))
#36 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#37 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
#38 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle(Object(Illuminate\Http\Request), Object(Closure))
#39 /app/app/Backpack/Http/Middleware/SetDefaultLocaleForm.php(22): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#40 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\Backpack\Http\Middleware\SetDefaultLocaleForm->handle(Object(Illuminate\Http\Request), Object(Closure))
#41 /app/app/Backpack/Http/Middleware/Permission.php(36): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#42 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\Backpack\Http\Middleware\Permission->handle(Object(Illuminate\Http\Request), Object(Closure))
#43 /app/app/Backpack/Http/Middleware/CheckIfAdmin.php(66): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#44 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\Backpack\Http\Middleware\CheckIfAdmin->handle(Object(Illuminate\Http\Request), Object(Closure))
#45 /app/app/Backpack/Http/Middleware/SetupMorphMap.php(20): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#46 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\Backpack\Http\Middleware\SetupMorphMap->handle(Object(Illuminate\Http\Request), Object(Closure))
#47 /app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(51): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#48 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Routing\Middleware\SubstituteBindings->handle(Object(Illuminate\Http\Request), Object(Closure))
#49 /app/vendor/backpack/crud/src/app/Http/Middleware/AuthenticateSession.php(62): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#50 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Backpack\CRUD\app\Http\Middleware\AuthenticateSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#51 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(88): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#52 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle(Object(Illuminate\Http\Request), Object(Closure))
#53 /app/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#54 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#55 /app/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#56 /app/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\Session\Middleware\StartSession->handleStatefulRequest(Object(Illuminate\Http\Request), Object(Illuminate\Session\Store), Object(Closure))
#57 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#58 /app/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#59 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure))
#60 /app/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(75): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#61 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Cookie\Middleware\EncryptCookies->handle(Object(Illuminate\Http\Request), Object(Closure))
#62 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#63 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(807): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#64 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(786): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
#65 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(750): Illuminate\Routing\Router->runRoute(Object(Illuminate\Http\Request), Object(Illuminate\Routing\Route))
#66 /app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(739): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#67 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(201): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#68 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request))
#69 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#70 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
#71 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle(Object(Illuminate\Http\Request), Object(Closure))
#72 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#73 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(51): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(Object(Illuminate\Http\Request), Object(Closure))
#74 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\TrimStrings->handle(Object(Illuminate\Http\Request), Object(Closure))
#75 /app/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#76 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Http\Middleware\ValidatePostSize->handle(Object(Illuminate\Http\Request), Object(Closure))
#77 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(110): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#78 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle(Object(Illuminate\Http\Request), Object(Closure))
#79 /app/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#80 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Http\Middleware\HandleCors->handle(Object(Illuminate\Http\Request), Object(Closure))
#81 /app/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(58): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#82 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Http\Middleware\TrustProxies->handle(Object(Illuminate\Http\Request), Object(Closure))
#83 /app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#84 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#85 /app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(145): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#86 /app/vendor/laravel/octane/src/ApplicationGateway.php(36): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#87 /app/vendor/laravel/octane/src/Worker.php(84): Laravel\Octane\ApplicationGateway->handle(Object(Illuminate\Http\Request))
#88 /app/vendor/laravel/octane/bin/roadrunner-worker(56): Laravel\Octane\Worker->handle(Object(Illuminate\Http\Request), Object(Laravel\Octane\RequestContext))
#89 /app/vendor/bin/roadrunner-worker(119): include('/app/vendor/lar...')
#90 {main}
"}

After huge session of the debug, I came to the conclusion that after several requests to the server, the workers start working incorrectly and the temporary file is deleted even before it is uploaded to the storage.

I noticed that an "created" event listener is set to upload files for creating models. This event listener defined in FileAdder:attachMedia method.

As a result, I decided to find out if Octane clears event listeners after each request and found no confirmation of this.

Then I've decided to made some tests, and placed "dump" function after ::created listener definition.

$class::created(function (Model $model) {
    /** @var Model&InteractsWithMedia $model */
    $model->processUnattachedMedia(function (Media $media, self $fileAdder) use ($model) {
        $this->processMediaItem($model, $media, $fileAdder);
    });
});

$listeners = app(Dispatcher::class)->getListeners("eloquent.created: {$class}");
dump($listeners, count($listeners));

For the first few requests, the number of listeners was 3 (another 2 listeners is for Telescope). Then, at some point, I got the error from the stacktrace above. The number of listeners increased to 4.

Then, as an experiment, I modified the listener code as follows.

$class::created(function (Model $model) {
    /** @var Model&InteractsWithMedia $model */
    $model->processUnattachedMedia(function (Media $media, self $fileAdder) use ($model) {
        // comparing fileAdder with current adder
        if ($fileAdder !== $this) {
            return;
        }

        $this->processMediaItem($model, $media, $fileAdder);
    });
});ё

After that, the error with the non-existent file stopped appearing.

I'm not sure, but It seems to me that after uploading the file, the event listener should be forcibly deleted, since, probably, in the case of using long-running servers, listeners will\can accumulate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant