Являє собою штатний рівень абстракції для задач, котрі вимагають кешування даних на певний час. Присутній у складі, починаючи з Ubilling 0.6.8. Усе брутально і прямолінійно як завжди. Реалізовано у вигляді класу UbillingCache і керується такими опціями alter.ini:
; Встановлює тип сховища системного кешу, можливі значення: ; files - у файлах, використовується за замовчуванням, не потребує конфігурації ; memcached - використовує Memcached для кешування даних в оперативній пам'яті на основі хеш-таблиць ; redis - використовує Redis як мережеве журнальоване сховище даних типу "ключ - значення" ; fake - фейковий кеш - вважається, що він завжди порожній UBCACHE_STORAGE=files ; Необов'язкові опції, що встановлюють, якщо потрібно, альтернативні параметри memcached і redis ;MEMCACHED_SERVER=localhost ;MEMCACHED_PORT=11211 ;REDIS_SERVER=localhost ;REDIS_PORT=6379 ;Вмикає запис логування роботи кешу в exports/cache.log. Воно дуже вбиває швидкодію і використовується тільки для налагодження. ;UBCACHE_DEBUG=1
Вся робота з класом намотана навколо методу getCallback:
$cache = new UbillingCache(); // створюємо об'єкт $cacheTime=60; // час кешування в секундах $someData = $cache->getCallback('EXAMPLE_KEY', function () { return (web_AnalyticsPaymentsMonthGraph('2015')); }, $cacheTime); //відображаємо результат show_window(__('Example data from cache'), $someData);
Варто зауважити, що ви можете не перейматися серіалізацією своїх даних під час засовування в кеш. На виході ви отримаєте той самий тип даних, який передбачався спочатку.
Для протягування властивостей вашого об'єкта всередину анонімної функції коллбека вам доведеться використовувати невеликий хак.
public function sampleFunction() { $result = ''; $this->initCache(); // тут ми ініціалізуємо загальний для об'єкта екземпляр кешу // а саме створюємо $this->cache і $this->timeout $obj = $this; // а ось власне і хак $result = $this->cache->getCallback('SAMPLE_FUNCT_CACHE', function() use ($obj) { return ($obj->getLargeData()); // на жаль getLargeData може бути тільки публічним методом }, $this->timeout); return ($result); }
Хоча дані з кеша самостійно видаляються після закінчення часу $expiration, що вказується в секундах, можливо, вам буде потрібно очистити дані кеша “ось прямо зараз”. Для примусового очищення конкретного ключа кеша, ми можемо використовувати публічний метод delete якось так:
$cache->delete('EXAMPLE_KEY');
Ви можете використовувати це все просто на рівні set/get, вказуючи час зберігання даних ключа в кеші. Так, у цьому разі нам доведеться самим вирішувати, коли і як засовувати дані в кеш, у разі його старіння/інвалідації.
Якось так:
$cache=new UbillingCache(); $cacheTime=60; $dataToPush='sample data'; //намагаємося отримати дані з кешу $dataInCache=$cache->get('CACHE_TEST_KEY', $cacheTime); if (!empty($dataInCache)) { //якщо щось отримано і воно не порожнє - показуємо це у віконці show_window(__('Data from cache'),$dataInCache); } else { //запихаємо дані в кеш на скільки нам потрібно часу $cache->set('CACHE_TEST_KEY', $dataToPush, $cacheTime); show_warning(__('No data in received, cache expired')); }
Слід також пам'ятати, що при прямій роботі за допомогою set/get рекомендується вказувати таймаут кешування в обох функціях. Оскільки для стораджів типу memcached або redis на таймаут зберігання даних впливає безпосередньо set, який реалізовано засобами самого сховища, а для сховища files з цілком зрозумілих причин актуальність даних, що містяться в ньому, перевіряється під час здійснення get (файли на ФС не вміють самі по собі видалятися, дивно, чи не так?).
Цілком зрозуміло, що для UBCACHE_STORAGE=memcached потрібен увімкнений і працюючий сам memcached.
/etc/rc.conf
memcached_enable="YES" memcached_flags="-l 127.0.0.1 -m 128 -I 10M"
# /usr/local/etc/rc.d/memcached restart
Припустимо, з якоїсь причини, вам хочеться в якомусь вашому, конкретному модулі використовувати сховище кешу, що відрізняється від зазначеного в опції UBCACHE_STORAGE. Припустимо, вам потрібно багато швидкого читання memcached, а для решти системи ви використовуєте redis, який у цьому конкретному випадку може виявитись менш продуктивним, виходячи з бенчмарків. Або ви використовуєте memcached з маленькими ключами, але вам різко потрібно покласти в кеш якийсь більший обсяг даних, що вміщується в files або redis, до якого ви не очікуєте дуже частих звернень. У такому разі, починаючи з релізу 1.1.5 ви можете використовувати перевизначення типу сховища прямо в конструкторі класу, наприклад так:
$this->cacheFiles = new UbillingCache('files'); // тут я хочу файловий кеш, "тому-що". $this->cacheRedis = new UbillingCache('redis'); // а для цього екземпляра - редис. // а в конфігурації для всієї іншої системи в нас буде взагалі memcached і все це тільки тому, що наркотики - зло.