Продвинутое

Файловое хранилище

Winter даёт персистентное key-value хранилище на файлах с необязательным сроком жизни. Оно доступно из FPM-воркеров, консольных команд и потомков-threads — без Redis. На нём же работают внутренние механизмы: передача данных в джобы, состояние демонов, кеш маршрутов.

Доступ Kernel::store()Класс FileStorageTTL абсолютный timestamp

Что такое файловое хранилище и зачем

Файловое хранилище — простое key-value на файлах, переживающее рестарт процесса.

Проблема. Иногда нужно сохранить немного данных между запросами или процессами — токены, коды подтверждения, счётчики троттлинга — но поднимать ради этого Redis избыточно.

Решение. Winter даёт файловое хранилище с TTL: положили по ключу, прочитали, пока не истёк срок. Об этом и раздел; для высоконагруженного кеша есть Redis.

Доступ

Kernel отдаёт именованное хранилище тремя методами — они различаются лишь базовой папкой:

php
public static function store(string $name, bool $isHash = true): FileStorage      // storage/cache
public static function runnable(string $name, bool $isHash = true): FileStorage   // storage/runnable
public static function volatile(string $name, bool $isHash = true): FileStorage   // storage/volatile

Для прикладного кеширования используйте store():

php
use Flytachi\Winter\K2\Kernel;

$store = Kernel::store('sessions');   // FileStorage в storage/cache/sessions

API FileStorage

php
public function write(string $key, mixed $content, ?int $expireAtTimestamp = null): void
public function read(string $key): mixed        // null, если нет или истёк
public function has(string $key): bool
public function del(string $key): void
public function keys(): array
public function clear(): void
public function gc(int $tmpMaxAgeSeconds = 3600): int
php
$store = Kernel::store('sessions');

$store->write('user:42', ['name' => 'Ada']);
$data = $store->read('user:42');        // ['name' => 'Ada'] или null

if ($store->has('user:42')) {
  $store->del('user:42');
}

Срок жизни (TTL)

Третий аргумент write()абсолютный UNIX-timestamp истечения, не относительная длительность:

php
$store->write('otp:42', '123456', time() + 300);   // валиден 5 минут
$code = $store->read('otp:42');                     // null после истечения

Пустое значение не пишется

write() с «пустым» содержимым ('', 0, null, [], false) — тихий no-op: такие значения сохранить нельзя. read() возвращает null и для отсутствующего, и для истёкшего ключа (не бросает). Значения сериализуются, запись атомарна (tmp-файл + rename), а gc() подчищает осиротевшие .tmp.

Где это используется в ядре

Хранилище — фундамент нескольких механизмов: передача полезной нагрузки в джобы (dispatch() кладёт данные в volatile), состояние демонов (runnable), кеш таблицы маршрутов. Ваш код работает с тем же API через Kernel::store().

Файлы vs Redis

Файловое хранилище Redis
Инфраструктура не нужна нужен Redis
Для чего токены, OTP, мелкие кеши горячий кеш, высокая нагрузка
TTL абсолютный timestamp нативные команды Redis

Дальше