laravel-bridge
laravel-bridge copied to clipboard
Missing override path for "real-time" facades
file_put_contents(/var/task/storage/framework/cache/facade-d6c8a1ed6fde286ae195e535517be856b15c1f39.php): failed to open stream: No such file or directory
Hi, have you tried upgrading to the latest version?
In the last version, I moved the cache directory in /tmp
, which should solve the problem with all cache directories.
Unfortunately it seems like the facade cache doesn't make use of the cache directory setting and makes raw calls to storage_path()
as seen here and here.
Do you think this needs to be fixed upstream instead?
I would think so yes (fix upstream) but it doesn't look like it will. I'm not sure what we can do though 🤔
I've been meditating about this issue and it really looks like we can do anything other than their proposed workaround if we want real time facades working on Bref 😔
Do you think it's better for me to polish that PR or do you have something different in mind?
EDIT: maybe overriding AliasLoader? https://laravel.com/docs/7.x/container#binding
@yangm97 I ran into the same issue, I ended up overriding AliasLoader.php and forcing it to use the tmp directory.
Maybe another option would be to mount an EFS volume for the storage directory: https://aws.amazon.com/blogs/compute/using-amazon-efs-for-aws-lambda-in-your-serverless-applications/
@tripper54 I wouldn't recommend EFS. From my tests it is much slower, it also requires a VPC and heavy setup with base costs. It's really good as a last resort solution.
I've hit this issue myself trying to get Livewire file uploads working. Livewire appears to be loading up some real-time facades, and those then try to be cached in /var/task/storage/framework/cache, as per the original issue described here.
My solution so far feels a bit hacky, but does work:
- I've created my own Application class, extending \Illuminate\Foundation\Application
- in bootstrap/app.php, I load my own class here to create $app:
$app = new App\Overrides\Application(
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);
- then in my custom Application class, I've overridden just the storagePath function, putting in a check for running on lambda, and then have it return just /tmp/ as the path if it's trying to write to framework/cache:
<?php
namespace App\Overrides;
class Application extends \Illuminate\Foundation\Application
{
public function storagePath($path = '')
{
$isRunningInLambda = isset($_SERVER['LAMBDA_TASK_ROOT']);
if ($isRunningInLambda && strpos($path, 'framework/cache/') === 0 ) {
$path = str_replace('framework/cache/', '', $path);
return '/tmp/' . $path;
}
return ($this->storagePath ?: $this->basePath.DIRECTORY_SEPARATOR.'storage')
.($path != '' ? DIRECTORY_SEPARATOR.$path : '');
}
}
I'm sure there are better ways to achieve this, but this at least feels predicable.
My solution was:
In bootstrap/app.php
$app->useStoragePath($_ENV['APP_STORAGE'] ?? (base_path() . '/storage'));
in .env
APP_STORAGE=/tmp/storage
in app/Providers/AppServiceProvider.php
public function boot()
{
$storagePath = config('cache.stores.file.path', '');
// Make sure the directory for local storage exists
if (! is_dir($storagePath)) {
mkdir($storagePath, 0755, true);
}
}
Will be solved in v2, see https://github.com/brefphp/laravel-bridge/pull/94