I am trying to store the last run time of a scheduled job in Laravel. However, the cache is not updating the date. I want the cache to be remembered until the function is called again.
public function setLastRun() {
Cache::forget('last_automation_api_run');
Cache::rememberForever('last_automation_api_run', function () {
return now()->toDateTimeString();
});
}
You should use remember and forget method in different functions.
public function getLastRun() {
return \Cache::rememberForever('last_automation_api_run', function () {
return now()->toDateTimeString();
});
}
public function forgetLastRun() {
\Cache::forget('last_automation_api_run');
}
Every time you delete the cache before fetching cache values makes, logically incorrect.
And you have to return the values coming from rememberForever cache method.
If you're using a clustered cache then there's a chance the first change hasn't propagated through the cache when you make the 2nd one. If that is the case (or generally for what you're doing) you can try the following:
public function setLastRun() {
Cache::put('last_automation_api_run', now()->toDateTimeString());
}
this should mindlessly overwrite the current value rather than deleting and readding it.
Related
New to laravel, In my case, I have 3 actions (move to active, inactive, and deleted)
when moved to active/inactive, the status column in database is changed,
when deleted, it gets soft deleted (without changing the status column),
Now, when the deleted rows are being moved to active/inactive, I should use restore() and at the same it, update the status column as specified.
But I can't find any docs regarding this use case.
You may write some helper method for Model to do though
I know this is not exactly the answer of your question but using these you can active/inactive your model without knowing about how it works and also it prevents redundant codes all over the project.
use Illuminate\Support\Facades\DB;
protected function toggleStatus($status) {
DB::transaction(function () use($status) {
$this->restore();
$this->update(['status' => $status]);
});
}
public function active() {
$this->toggleStatus('active');
}
public function inactive() {
$this->toggleStatus('inactive');
}
I need to compare original model values with changes that are done when update occurs, but I am not able to do that.
My model update code looks like this:
public function update(array $user, int $userId): ?bool
{
return User::find($userId)->update($user);
}
I thought that the best way to capture changes is to use observer and observe updating event, because I assume it's called right before changes are stored in the database. Here is updating method code:
public function updating(User $user)
{
Log::info('Original user', ['original' => $user->getRawOriginal('status')]);
}
I've tried logging a bit and it seems that updating method gets called after the update happens and then when I try to retrieve original model values there it returns new ones, instead of the original ones.
If I use getChanges() method in updating it returns exactly what has changed, so it seems that changes are tracked somehow, but not the original values?
Can someone give me any pointers how to solve this and explain to me why my approach doesn't work?
Update: Code, where I call update, is wrapped with DB transaction methods. After removing them it seems that updating method gets called at the right time and getRawOriginal then returns expected results.
In this case, what are my options? Is there a way to do what I want without removing transactions?
You can add boot method in your model .Both updating and updated trigger while updating .
protected static function boot()
{
parent::boot();
static::updating(function ($model){
echo "updating";
dump($model->getDirty());
dump($model->getRawOriginal('username'));
});
static::updated(function ($model){
echo "updated";
dump($model->getDirty());
dump($model->getRawOriginal('mobile_number'));
});
}
In my laravel app, I noticed that every route is executed twice, and can't figure out why
for example:
Route::get('called_twice', function () {
dump('---');
});
return string '---' twice
Edit:
trying to backtrace the source of the issue, I put a dump in file
src/Illuminate/Foundation/Http/Kernel.php
protected function sendRequestThroughRouter($request)
{
$this->app->instance('request', $request);
Facade::clearResolvedInstance('request');
$this->bootstrap();
dump('kernel');
return (new Pipeline($this->app))
->send($request)
->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
->then($this->dispatchToRouter());
}
and another dump in the constructor of the file
src/Illuminate/Pipeline/Pipeline.php
public function __construct(Container $container = null)
{
dump('pipeline');
$this->container = $container;
}
and I get this:
the Pipeline class is called many time
Laravel 6.8.0
I think $next($request) is probably called twice in a middleware. The reason is that the response is passed throught each middleware (pipes) before it is returned back.
So if $next($request) is called twice in one middleware it is normal that all pipes will be called again.
Found mine in the master. there was a script that was causing the page to reload in the background.
I built a little counter with admin access only and smoked it out. Came down to one script.
Error is:
Serialization of 'Closure' is not allowed
Error at:
.../vendor/laravel/framework/src/Illuminate/Cache/RedisStore.php:295
Throws when remembering forever on Cache for the first time.
After second try (when reloading browser) it works as it should work.
public function cache()
{
$task = $this;
return Cache::rememberForever('apply:' . $task->apply->slug . ':' . $task->slug, function () use ($task) {
return $task;
});
}
Interesting part is this. So it works on caching $apply on Apply's index page. (The code is the same)
Note: This issue is related to Redis directly. Please don't mention old questions about serialization. You can check official Laravel 6.x documentation too. Everything is added related to it: https://laravel.com/docs/6.x/cache#retrieving-items-from-the-cache
I fixed it by manually storing and returning data if it exists on cache (how rememberForever() should be work).
public function cache () {
$slug = 'task:'.$this->slug;
if(Cache::has($slug)) return Cache::get($slug);
if(!Cache::put($slug, $this)) throw new ProtocolException(1045);
return Cache::get($slug);
}
Is that a good practise to store a void value as that?
Cache::remember($cacheName, $this->time, function() use ($data) {
$this->someTransformation($data, ['title', 'url']);
return 1;
});
The point is: when I do not return anything from remember method - nothing is cached and I have to call someTransformation which includes some API calls again. This seems like it's working but I am not sure about whether there is not anything better.