Jobleads Cache
What solutions we are using?
- Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache, and message broker. Redis provides data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes, and streams.
- Redis Sentinel is the high availability solution offered by Redis. In case of a failure in your Redis cluster, Sentinel will automatically detect the point of failure and bring the cluster back to stable mode without any human intervention.
What solutions we are using?

How it's configured in portal project?
- Connection information is stored in config/autoload/sentinel.local.php
- Connection is provided by Predis instead of the native PHP extension
- Laminas haven't native support for Predis. For configuration purpose we have: "jobleads/sentinel": "^1.0"
How it's configured in portal project?
return [
SentinelsConfig::class => [
'sentinels' => [
[$sentinelHost1, 26379],
[$sentinelHost2, 26379],
],
'master_sets' => [
'ems' => $masterSet . '?database=' . ConnectionPool::DATABASE_VALUE_EMS, // it means that from the redis connection pool it is fetchable via $pool->ems() method
'cache' => $masterSet . '?database=' . ConnectionPool::DATABASE_VALUE_CACHE, // it means that from the redis connection pool it is fetchable via $pool->cache() method
'rto' => $masterSet . '?database=' . ConnectionPool::DATABASE_VALUE_RTO, // it means that from the redis connection pool it is fetchable via $pool->rto() method
'session' => $masterSet . '?database=' . ConnectionPool::DATABASE_VALUE_SESSION, // it means that from the redis connection pool it is fetchable via $pool->session() method
'jobpool' => $masterSet . '?database=' . ConnectionPool::DATABASE_VALUE_JOB_POOL, // it means that from the redis connection pool it is fetchable via $pool->jobpool() method
'payment' => $masterSet . '?database=' . ConnectionPool::DATABASE_VALUE_PAYMENT, // it means that from the redis connection pool it is fetchable via $pool->payment() method
'messenger' => $masterSet . '?database=' . ConnectionPool::DATABASE_VALUE_MESSENGER, // it means that from the redis connection pool it is fetchable via $pool->messenger() method
'jobArchive' => $masterSet . '?database=' . ConnectionPool::DATABASE_VALUE_JOB_HISTORY_ARCHIVE, // it means that from the redis connection pool it is fetchable via $pool->jobArchive() method
],
],
];What is the right way to use cache?
Use laminas-cache instead of direct connection!
public function __invoke(ContainerInterface $container)
{
return new QueryCacheManager(
$container->get(CacheManagerInterface::APPLICATION_CACHE)
);
}This code will produce instance of
Laminas\Cache\Storage\StorageInterface
for you and now you can go!
What means "storage"?
Storage can be reconized as already configured adapter.
CacheManagerInterface::APPLICATION_CACHE => [
'plugins' => ['serializer'],
'options' => [
'sentinel_masterset' => ConnectionPool::CACHE_MASTERSET,
],
'adapter' => [
'name' => PredisCacheAdapter::class,
'options' => [
'namespace' => 'config_cache_'
],
],
],This config is present in
module/Application/config/cache.config.php
and all declared Storages are available via Laminas service locator
Is StorageInterface PSR compliant?

How to make StorageInterface PSR compliant?
- For PSR-6 you need to use
Laminas\Cache\Psr\CacheItemPool\CacheItemPoolDecorator
$pool = new CacheItemPoolDecorator($storage);- For PSR-16 you need to use
Laminas\Cache\Psr\SimpleCache\SimpleCacheDecorator
$cache = new SimpleCacheDecorator($storage);How to NOT use cache?
- Do not use Predis directly in your code!
- ConnectionPoolAwareFactory can be used only in very specialized situation, e.g. if you need native data structures avaible only in redis
class QueryCacheManagerFactory extends ConnectionPoolAwareFactory
{
public function __invoke(ContainerInterface $container, Client $client)
{
return new QueryCacheManager(
$client
);
}
}DO NOT DO THAT!!!
Conclusion

JobLeads Cache
By Piotr Woszczyk
JobLeads Cache
- 68