Summary
Classname
Cache
Namespace
Ufo\RpcObject\RPC
Target
method
Constructor
/**
* Cache constructor.
*
* @param int $lifetimeSecond
* @param array $environments
*/
public function __construct(
public int $lifetimeSecond = self::T_MINUTE,
public array $environments = [self::ENV_PROD],
) {}
Кешування відповіді методу
За замовченням кешування відповідей ваших RPC методів вимкнено і кожен раз, коли ви викликаєте API, метод буде викликано.
Проте, інколи, для певних методів, результат яких змінюється не часто, є сенс ввімкнути кешування відповіді задля підвищення швидкості обробки запитів, для збереження лімітів, зниження навантаження на частини системи, тощо.
Відповіді зберігаються в окремому пулі кешу бандла (rpc.cache.pool, файловий у %kernel.cache_dir%). Його можна замінити будь-яким пулом застосунку, наприклад спільним Redis, через cache.pool у налаштуваннях.
Ввімкнути кешування максимально просто, єдине що вам потрібно зробити це до певного методу додати атрибут #[RPC\Cache].
namespace App\Api\Procedures;
use Ufo\RpcObject\RPC;
class SomeApiMethod implements IRpcService
{
#[RPC\Cache]
public function methodThatWorksForALongTime(): void {}
}
Це налаштування дозволить кешувати відповідь впродовж однієї хвилини, кожен наступний запит на цей метод з тими самими параметрами буде отримувати відповідь миттєво з кеша.
Ключ кешу складається з реалізації методу (Class::method), версії API та відсортованих параметрів запиту, тож порядок ключів у вкладених об'єктах на ключ не впливає. Методи без #[RPC\Cache] до кешу взагалі не звертаються.
Скинути кеш можна як і завжди, виконавши Symfony команду
bin/console cache:clear
В разі потреби ви можете збільшити час життя кеша, передавши кількість секунд в параметр lifetimeSecond. Для зручності створені константи, які покривають більшість потреб, але ви також можете передати значення простим числом.
use Ufo\RpcObject\RPC\Cache;
Cache::T_MINUTE; // 60
Cache::T_5_MINUTES; // 300
Cache::T_10_MINUTES; // 600
Cache::T_30_MINUTES; // 1800
Cache::T_HOUR; // 3600
Cache::T_2_HOURS; // 7200
Cache::T_5_HOURS; // 18000
Cache::T_10_HOURS; // 36000
Cache::T_DAY; // 86400
Cache::T_2_DAYS; // 172800
Cache::T_3_DAYS; // 259200
Cache::T_5_DAYS; // 432000
Cache::T_10_DAYS; // 864000
Cache::T_WEEK; // 604800
Cache::T_2_WEEKS; // 1209600
Cache::T_3_WEEKS; // 1814400
Cache::T_MONTH; // 2592000
Cache::T_2_MONTHS; // 5184000
Cache::T_3_MONTHS; // 7776000
Cache::T_HALF_YEAR; // 15724800
Cache::T_YEAR; // 31536000
Також ви можете змінити налаштування оточення на якому кеш може бути ввімкнений. За замовченням кешування працює лише в оточенні prod. Але ви можете це змінити передавши масивом назви оточень, в яких хочете кешувати результати. У прикладі нижче результат буде кешуватися протягом однієї доби для prod і dev оточень.
namespace App\Api\Procedures;
use Ufo\RpcObject\RPC;
class SomeApiMethod implements IRpcService
{
#[RPC\Cache(lifetimeSecond: RPC\Cache::T_DAY, environments: ['dev', 'prod'])]
public function methodThatWorksForALongTime(): void {}
}
Обійти кеш для одного запиту
Спеціальний параметр $rpc.ignoreCache змушує обчислити відповідь заново й перезаписати її в кеші:
{"jsonrpc": "2.0", "id": 1, "method": "SomeApiMethod.methodThatWorksForALongTime", "params": {"$rpc": {"ignoreCache": true}}}
#[RPC\CacheRelation]
Метод, що змінює дані, може скидати закешовані відповіді пов'язаних методів і, за потреби, одразу прогрівати їх знову.
public function __construct(
public ?string $serviceFQCN = null, // клас пов'язаних методів; за замовчуванням — поточний
public array $methods = [], // назви пов'язаних методів
public bool $warmUp = false, // одразу виконати їх знову, щоб наповнити кеш
)
use Ufo\RpcObject\RPC;
#[RPC\Info('User')]
final class UserProcedure implements IRpcService
{
#[RPC\Cache(lifetimeSecond: RPC\Cache::T_HOUR)]
public function get(int $id): UserDto { /* ... */ }
#[RPC\CacheRelation(methods: ['get'], warmUp: true)]
public function rename(int $id, string $name): bool { /* ... */ }
}
Після успішного User.rename {"id": 5, ...} закешований User.get {"id": 5} видаляється і будується заново. Ключ пов'язаного запиту складається з тих параметрів поточного запиту, чиї назви збігаються з параметрами пов'язаного методу. Атрибут можна вказувати кілька разів.
Інвалідація виконується на події rpc.post_response, тобто після відправлення відповіді клієнту. Для відповіді з помилкою вона не запускається.
На кількох серверах налаштуйте спільний cache.pool — інакше інвалідація спрацює лише на сервері, що обробив запит.
Керування кешем з коду
Ufo\JsonRpcBundle\Server\RpcCache\RpcCacheService дає ті самі можливості програмно:
| Метод | Що робить |
|---|---|
deleteRelationCache(string $class, array $methods, array $params) |
Видаляє кешовані відповіді вказаних методів |
warmCache(string $class, array $methods, array $params, bool $deleteCache = true) |
Видаляє й одразу заново будує кеш |
deleteRequestCache(RpcRequest $request) |
Видаляє відповідь одного запиту |
public function __construct(private RpcCacheService $rpcCache) {}
// після оновлення сутності поза RPC
$this->rpcCache->deleteRelationCache(UserProcedure::class, ['get'], ['id' => $id]);