У меня в таблице users есть поле кредитов, которое уменьшается на 1 при каждом запросе пользователя API сайта. Вместо чтения/записи в базу данных по каждому запросу я думал об использовании кеша.Обновление БД при истечении срока действия кеша?
Так по первому требованию я захватить кредиты налево, как следствие запрос я уменьшаем на 1 значение кэша, а затем в какой-то момент я обновляю дб ...
Так что я создал промежуточное программное обеспечение, что в основном делает:
public function handle($request, Closure $next)
{
// check api key
$user = User::where(['api_token' => $request->input('license')])->first();
if(! $user)
return \Response::json(['error' => 'The provided License key is not valid.'], 403);
// check credits
$cache_key = 'user_'.$user->id.'_credits';
$credits = Cache::remember($cache_key, 1, function ($u) use ($user) {
return $u->credits;
});
$credits::decrement($cache_key);
//update db on cache expiration ?
return $next($request);
}
Но теперь я не уверен, когда я должен обновить базу данных новым значением кеша или если это хорошая практика вообще?
В основном я пытаюсь работать с кешем вместо базы данных по каждому запросу.
ОБНОВЛЕНИЕ: После проверки ответа @antonio мои функции заканчиваются, как приведенный ниже код. Проблема, которую я вижу, заключается в том, что $ model-> credits не обновляется до истечения срока действия кеша. Но мне нужно это при каждом вызове, чтобы проверить, потребляет ли пользователь больше кредитов, чем у них, или посмотреть, запускаю ли я событие автоматической покупки.
public function handle($request, Closure $next)
{
// Create a cache key based on the license
$cache_key = 'user_'.($license = $request->input('license'));
// Remember will return a cached user if the license is cached
$model = Cache::remember($cache_key, 1, function() use ($license) {
// find the user by the license
if(! $user = User::where(['api_token' => $license])->first()) {
// This license does not exists, return a response instead
return \Response::json(['error' => 'The provided License key is not valid.'], 403);
}
// return the user or response
return $user;
});
// If it is a response, break and return it
if ($model instanceof Response || $model instanceof JsonResponse) {
return $model;
}
// TODO Validate domain
//dd($_SERVER['HTTP_REFERER']); or use CORS or embed site_url in request?
// Decrement the credits
$model::decrement('credits');
// Autobuy zone
if($model->credits == $model->auto_buy_amount)
event(new CreditsLimitReached($model));
// No more credits
if($model->credits < 1 && ! $model->nocredits_email){
$model->nocredits_email = true;
$model->save();
// TODO clean no credits emails every day
event(new OutOfCredits($model));
return \Response::json(['error' => 'You run out of credits.'], 403);
}
// Go to the next middleware
return $next($request);
}
Возможно, мой вопрос должен состоять в том, как бы вы написали что-то вроде этого. В основном мне нужно выполнить 3 задачи на этом промежуточном программном обеспечении, когда пользователь выполняет вызов api 1- Сокращение кредитов на 1 2- Проверьте, достиг ли пользователь зоны покупки и события пожара 3- Проверьте, не закончился ли у пользователя кредит и (в основном электронная почта, позволяющая им знать, что закончились кредиты)
Спасибо, это имеет смысл! – chifliiiii
Привет @ antonio-carlos-ribeiro, к сожалению, это не работает должным образом. Проблема заключается в том, что хотя модель: декремент ('credits') уменьшает -1 в базе данных, $ model-> credits не обновляется до истечения срока действия кэша – chifliiiii