Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support 'safe_load' directive #177

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/php.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ jobs:
restore-keys: |
${{ runner.os }}-php-

- name: PHP info
run: php -v && composer -V

- name: Install dependencies
run: composer install --prefer-dist --no-progress

Expand Down
14 changes: 8 additions & 6 deletions Cm/Cache/Backend/Redis.php
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,8 @@ public function __construct($options = array())
if (isset($options['auto_expire_refresh_on_load'])) {
$this->_autoExpireRefreshOnLoad = (bool) $options['auto_expire_refresh_on_load'];
}

$this->_directives['safe_load'] = false;
}

/**
Expand Down Expand Up @@ -481,7 +483,7 @@ protected function _setupReadWriteCluster($options)
*/
public function load($id, $doNotTestCacheValidity = false)
{
if ($this->_slave) {
if ($this->_slave && empty($this->_directives['safe_load'])) {
try {
$data = $this->_slave->hGet(self::PREFIX_KEY.$id, self::FIELD_DATA);

Expand Down Expand Up @@ -951,8 +953,8 @@ protected function _collectGarbage()

// TODO
// Clean up global list of ids for ids with no tag
// if ($this->_notMatchingTags) {
// }
// if ($this->_notMatchingTags) {
// }
}

/**
Expand Down Expand Up @@ -1194,7 +1196,7 @@ public function getFillingPercentage()
}
$info = $this->_redis->info();
return (int) round(
($info['used_memory']/$maxMem['maxmemory']*100)
($info['used_memory'] / $maxMem['maxmemory'] * 100)
);
}

Expand All @@ -1213,10 +1215,10 @@ public function getHitMissPercentage()
}
$hits = $info['keyspace_hits'];
$misses = $info['keyspace_misses'];
$total = $misses+$hits;
$total = $misses + $hits;
$percentage = 0;
if ($total > 0) {
$percentage = round($hits*100/$total);
$percentage = round($hits * 100 / $total);
}
return $percentage;
}
Expand Down
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,22 @@ Works with any Zend Framework project including all versions of Magento!

# FEATURES

- Uses the [phpredis PECL extension](https://github.com/nicolasff/phpredis) for best performance (requires **master** branch or tagged version newer than Aug 19 2011).
- Can take advantage of the [phpredis PECL extension](https://github.com/phpredis/phpredis) for best performance if it is installed.
- Falls back to standalone PHP if phpredis isn't available using the [Credis](https://github.com/colinmollenhour/credis) library.
- Tagging is fully supported, implemented using the Redis "set" and "hash" data types for efficient tag management.
- Key expiration is handled automatically by Redis.
- Supports unix socket connection for even better performance on a single machine.
- Supports configurable compression for memory savings. Can choose between gzip, lzf and snappy and can change configuration without flushing cache.
- Supports configurable compression for memory savings. Can choose between gzip, lzf, l4z, snappy and zstd and can change configuration without flushing cache.
- Uses transactions to prevent race conditions between saves, cleans or removes causing unexpected results.
- Supports a configurable "auto expiry lifetime" which, if set, will be used as the TTL when the key otherwise wouldn't expire. In combination with "auto expiry refresh on load" offers a more sane cache management strategy for Magento's `Enterprise_PageCache` module.
- Supports reading from slaves, can be overridden at run time by setting the 'safe_load' directive.
- Can read connection info from Redis Sentinel for automatic failovers.
- __Unit tested!__

# REQUIREMENTS

As this backend uses [Credis](https://github.com/colinmollenhour/credis) there are no additional requirements, but for improved performance you can install [phpredis](https://github.com/nicolasff/phpredis) which is a compiled extension.

* For 2.4 support you must use the "master" branch or a tagged version newer than Aug 19, 2011.
* phpredis is optional, but it is much faster than standalone mode
* phpredis does not support setting read timeouts at the moment (see pull request #260). If you receive read errors (“read error on connection”), this
might be the reason.
This backend uses the [Credis](https://github.com/colinmollenhour/credis) library.
Optionally, but for improved performance, you can install [phpredis](https://github.com/phpredis/phpredis) which is a compiled extension and available via pecl and many official packages.

# INSTALLATION

Expand Down
7 changes: 7 additions & 0 deletions tests/CommonBackendTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ public function testSaveWithSpecificLifeTime(): void
$this->assertTrue($res);
}

public function testSaveWithEmptyString(): void
{
$this->_instance->setDirectives(array('lifetime' => 3600));
$this->assertTrue($this->_instance->save('', 'empty'));
$this->assertEquals('', $this->_instance->load('empty'));
}

public function testRemoveCorrectCall(): void
{
$this->assertTrue($this->_instance->remove('bar'));
Expand Down
10 changes: 8 additions & 2 deletions tests/RedisBackendTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public function testCleanModeMatchingAnyTags4(): void
public function testCleanModeMatchingAnyTags5(): void
{
$tags = array('tag1', 'tag4');
for ($i = 0; $i < self::LUA_MAX_C_STACK*5; $i++) {
for ($i = 0; $i < self::LUA_MAX_C_STACK * 5; $i++) {
$this->_instance->save('foo', 'foo'.$i, $tags);
}
$this->assertGreaterThan(self::LUA_MAX_C_STACK, count($this->_instance->getIdsMatchingAnyTags($tags)));
Expand All @@ -187,7 +187,7 @@ public function testCleanModeMatchingAnyTags5(): void
public function testCleanModeMatchingAnyTags6(): void
{
$tags = array();
for ($i = 0; $i < self::LUA_MAX_C_STACK*5; $i++) {
for ($i = 0; $i < self::LUA_MAX_C_STACK * 5; $i++) {
$tags[] = 'baz'.$i;
}
$this->_instance->save('foo', 'foo', $tags);
Expand All @@ -213,4 +213,10 @@ public function testScriptsCaching(): void
$this->_instance->clean(Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, ['x']);
$this->assertEquals(['clean'], $this->_instance->___checkScriptsExist());
}

public function testSafeLoad(): void
{
$this->_instance->setDirectives(['safe_load' => true]);
$this->assertTrue(true);
}
}