Open mathieufrh opened 4 months ago
Hi @mathieufrh,
The LARACACHE_MODELS_LIST
variable is used in the lower layers of the nova-laracache
package. it doesn't have anything to do with laracache
's laracache.list
. You don't need to use or change it.
I couldn't reproduce the bug. if you don't set any type of expiration (validForRestOfWeek
, validForRestOfDay
, plain ttl
, etc), the default TTL will be set to 0
, meaning the cached entity remains valid forever.
I believe this error might have occurred because you manipulated the content of LARACACHE_MODELS_LIST
yourself.
This list should be an empty array or an array containing strings representing the names of all cached models.
If you changed something and it contains non-string values, you will get an error with the array_unique
function.
That list is not an associative array, so it's not valid.
Overall, as mentioned in the documentation, to use nova-laracache
, you should first read the documentation of laracache
itself.
Your questions:
it simply indicates that the content of your cache entity is created and functional. Since some cache entities are heavy tasks to calculate and may need to be executed in the background, creating them might take a few seconds, during which time you should see the not-created
status. Moreover, if you've disabled cache generation on created
, updated
, etc, cache items will only be generated when someone hits them. So, seeing not-created
is normal based on your usage.
All actions happen in background jobs. if you are using a queue driver other than sync
to perform all actions (delete, refresh, etc.), you must run php artisan queue:work
through your terminal.
As explained here, just add it to your nova tools in NovaServiceProvider
But remember that this package works based on laracache
, and to learn to work with laracache
itself, you must read its documentation first.
Thank you very much for your answer.
I have installed Laracache and it is working:
I ran php artisan laracache:update -m Client
.
Then
> Client::cacheEntities()
= [
Mostafaznv\LaraCache\CacheEntity {#6206
+name: "list.forever",
+driver: "redis",
+forever: true,
+isQueueable: false,
+queueName: "default",
+queueConnection: "redis",
+validForRestOfDay: false,
+validForRestOfWeek: false,
+ttl: 0,
+refreshAfterCreate: true,
+refreshAfterUpdate: true,
+refreshAfterDelete: true,
+refreshAfterRestore: true,
+default: null,
+cacheClosure: Closure() {#6209 …3},
},
Mostafaznv\LaraCache\CacheEntity {#6208
+name: "latest",
+driver: "redis",
+forever: false,
+isQueueable: false,
+queueName: "default",
+queueConnection: "redis",
+validForRestOfDay: true,
+validForRestOfWeek: false,
+ttl: 0,
+refreshAfterCreate: true,
+refreshAfterUpdate: true,
+refreshAfterDelete: true,
+refreshAfterRestore: true,
+default: null,
+cacheClosure: Closure() {#6207 …3},
},
]
Then with Client::cache()->get('list.forever')
I get all the client records.
Now I have installed fresh version of nova-laracache using composer, I add it to the tools method of the NovaServiceProvider class. But when I go in the frontend page here is what I have :
I add a debug message in the models method of the ApiController class :
protected function models(): array
{
$models = [];
$key = UpdateLaraCacheModelsList::LARACACHE_MODELS_LIST;
$list = Cache::driver($this->driver)->get($key);
$list = is_array($list) ? $list : [];
$list = Arr::sort($list);
\Debugbar::info($list);
foreach ($list as $item) {
$model = $this->model($item);
if (method_exists($model, 'cacheEntities')) {
$models[] = $model;
}
}
return $models;
}
And this is what I get :
I don't know where those integers come from. So I clear the cache, then the debug message shows an empty array, great. I reload the cache frontend page and now it is better, except that no it fails trying to parse the ttl :
Which is expected since the line
$expiration = Carbon::createFromTimestamp($cache->expiration);
of the entityToArray
method, receives null.
However, you're right, the ttl is 0 :
Mostafaznv\LaraCache\CacheEntity {#6167
+name: "list.forever",
+driver: "redis",
+forever: true,
+isQueueable: false,
+queueName: "default",
+queueConnection: "redis",
+validForRestOfDay: false,
+validForRestOfWeek: false,
+ttl: 0,
+refreshAfterCreate: true,
+refreshAfterUpdate: true,
+refreshAfterDelete: true,
+refreshAfterRestore: true,
+default: null,
+cacheClosure: Closure() {#6164 …3},
},
Still it fails. Changing the line with $expiration = Carbon::createFromTimestamp($cache->expiration ?? 0);
make everything work.
But maybe it is because of my code. The static aspect of the cacheEntities method is not convenient for many some cases. So I decided to test and build the CacheEntity using database records. I know it's not a good practice to store code in the database, and I'm not very happy with this, but I am simply tinkering with the solution ow. So here is the code :
<?php
namespace App\Models\Concerns;
use App\Models\CacheEntity as CacheEntityModel;
use Mostafaznv\LaraCache\CacheEntity;
use Mostafaznv\LaraCache\Traits\LaraCache;
trait Cacheable
{
use LaraCache;
public const int VALID_FOR_REST_OF_WEEK = -1;
public const int VALID_FOR_REST_OF_DAY = -2;
/**
* Get all cache entities, including dynamic ones.
*
* @return array<CacheEntity>
*/
public static function cacheEntities(): array
{
return array_merge(self::getStaticEntities(), self::getDynamicEntities());
}
/**
* Get static cache entities.
*
* @return array<CacheEntity>
*/
private static function getStaticEntities(): array
{
return [
CacheEntity::make('list.week')->validForRestOfWeek()->cache(fn() => static::query()->latest()->get()),
CacheEntity::make('latest')->validForRestOfDay()->cache(fn() => static::query()->latest()->first()),
];
}
/**
* Get dynamic cache entities.
*
* @return array<CacheEntity>
*/
private static function getDynamicEntities(): array
{
$dynamicEntities = cache()->remember(
'dynamic_entities_' . static::class,
5,
fn() => CacheEntityModel::where('model', static::class)->get()
);
return $dynamicEntities->map(function ($dynamicEntity) {
$entity = CacheEntity::make($dynamicEntity->name)
->cache(fn() => ($dynamicEntity->callback)());
return self::applyDuration($entity, $dynamicEntity->duration);
})->toArray();
}
/**
* Apply duration to the cache entity.
*
* @param CacheEntity $entity
* @param int|null $duration
* @return CacheEntity
*/
private static function applyDuration(CacheEntity $entity, ?int $duration): CacheEntity
{
if ($duration === self::VALID_FOR_REST_OF_WEEK) {
return $entity->validForRestOfWeek();
}
if ($duration === self::VALID_FOR_REST_OF_DAY) {
return $entity->validForRestOfDay();
}
if ($duration) {
return $entity->ttl($duration);
}
return $entity->ttl(0);
}
}
Do you think there is something wrong in it ?
Thank you for your detailed report and investigations.
However, I believe if you reinstall both laracache
and nova-laracache
, and also clear your project's cache using php artisan cache:clear
or Cache::flush();
, your project will work properly.
In case the above instructions don't work, it would be helpful if you could provide me with a reproduction GitHub repo, so I can check it better and in detail.
Hello,
First I'd like to thank you for creating and sharing this package, along with the laracache package.
However I've encounter multiple bugs when using this package.
public const LARACACHE_MODELS_LIST = 'laracache.models';
is hardcoded and does not correspond with the default laracache config'laracache-list' => 'laracache.list',
.$expiration = Carbon::createFromTimestamp($cache->expiration);
throw an exception when not specifying expiration date for the cache entry.There are many exceptions during the jobs execution, like
ErrorException: Array to string conversion in /var/www/html/vendor/mostafaznv/laracache/src/Jobs/UpdateLaraCacheModelsList.php:38
. This one can be fixed in the same way as the next issue :In the ApiController I've add to change this line :
can you confirm those are bugs or am I using this package wrong ?
Overall, I think that those package would benefit of an enhanced documentation with some examples. I have no doubt those packages are working well but it's frustrating knowing it and not be able to make them work.
Well, now it is working and I can see the components in the ache tool.
Still, I have some questions: