Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
TagAwareAdapter over non-binary memcached connections corrupts memcache#27416
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
nicolas-grekas commentedMay 30, 2018
This approach doesn't work, eg. a simple space is also forbidden in keys when using the non binary protocol. Instead of changing the prefix for all backends (which has the downside of invalidating all existing pools btw), we should consider encoding keys, only in the memcached adapter. |
| * | ||
| * @param $key | ||
| */ | ||
| privatestaticfunctionencodeKey($key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I would suggest to inline the function and remove the method.
| } | ||
| $this->maxIdLength -=strlen($client->getOption(\Memcached::OPT_PREFIX_KEY)); | ||
| $this->client =$client; | ||
| $this->isTextProtocol = !$client->getOption(\Memcached::OPT_BINARY_PROTOCOL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
What do you think of always encoding the key, binary or not? That'd make the stored data independent from the actual protocol.
palex-fptMay 30, 2018 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
It adds some overhead. But it should not be high. There're two possible problems:
- client loses control over cache keys (mcrouter uses key names for app-level routing)
- non-symfony and/or non-php clients would have difficulties to share cache.
I don't share memcache with non-symfony apps, so I`m ok with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I think that's ok: the overhead should be negligible vs the network round-trips, and url encoding preserves most of the chars in the keys, making them still handleable.
Note that keys should be decoded on retrieval.
| if ($this->isTextProtocol) { | ||
| $encoded_values =array(); | ||
| array_walk($values,function ($value,$key)use (&$encoded_values) {$encoded_values[rawurlencode($key)] =$value; }); |
nicolas-grekasMay 30, 2018 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I generally don't like array_walk(), too much references there. Should be done with a foreach instead.
The temp var should use camel case coding name also.
nicolas-grekas commentedMay 30, 2018
All methods should encode/decode on read/write. Some are missing for now. |
nicolas-grekas commentedMay 30, 2018
(but tests fail) |
| ); | ||
| } | ||
| publicfunctiontestNonBinaryMemcachedMode() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Instead of adding a few new tests for that, covering only a small part of the API, I think we should instead have a separate test case overridingcreateCachePool, to run the full adapter tests in non-binary mode
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
MemcachedAdapterTest tests MemcachedAdapter::createConnection only. Should I add separate test classes to test MemcachedAdapter get, set, etc.. methods in text and binary modes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
It looks like I should add key containing \0 and spaces into \Cache\IntegrationTests\SimpleCacheTest::validKeys
This way it would be tested against all cache implementations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Or rely on the namespace to do so?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I added 'si\0mp le' key to \Cache\IntegrationTests\SimpleCacheTest::validKeys and ran tests local. All cache tests succeeded.
| $encodedValues[rawurlencode($key)] =$value; | ||
| } | ||
| return$this->checkResultCode($this->getClient()->setMulti($encodedValues,$lifetime)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
this is not decoding keys in the returned value. Can it have keys in it ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
\Memcached::setMulti returns bool. Did I missed something else?
6ce07dd to96c6cf9Compare| { | ||
| $client =$defaultLifetime ? AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'),array('binary_protocol' =>false)) :self::$client; | ||
| returnnewMemcachedCache($client,str_replace('\\','.',__CLASS__),$defaultLifetime); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Since the 2nd arg here is the namespace and is part of the key passed to memcached, we could add\0 and spaces to test the encoding?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
base test \Symfony\Component\Cache\Tests\Simple\CacheTestCase::validKeys adds\0 to tested keys
…d connection in ascii mode
nicolas-grekas commentedJun 8, 2018
Thank you@palex-fpt. |
…upts memcache (Aleksey Prilipko)This PR was merged into the 3.4 branch.Discussion----------TagAwareAdapter over non-binary memcached connections corrupts memcache| Q | A| ------------- | ---| Branch? | 3.4| Bug fix? | yes| New feature? | no| BC breaks? | no| Deprecations? | no| Tests pass? | no| Fixed tickets |#27405| License | MIT| Doc PR |TagAwareAdapter uses non-ascii symbols in key names. It breaks memcached connections in non-binary mode.Commits-------67d4e6d bug#27405 [Cache] TagAwareAdapter should not corrupt memcached connection in ascii mode
TagAwareAdapter uses non-ascii symbols in key names. It breaks memcached connections in non-binary mode.