-
Notifications
You must be signed in to change notification settings - Fork 53
Conversation
The implementation looks good. There were some small bugs thou.. Say you do like this: $item = $pool->getItem('key');
$item->set('foo');
$pool->saveDeferred($item);
$item = $pool->getItem('key');
$item->set('bar');
// No save
$item = $pool->getItem('key');
$item->get(); // should be 'foo' I added the integration tests with this PR: https://github.com/kynx/zend-cache/pull/1 |
*/ | ||
public function get() | ||
{ | ||
return $this->value; |
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.
You need to check if isHit before you return anything
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.
The value is set to null
in the constructor if the item isn't a hit.
Hi @kynx thanks for your work! I have added some notes from a quick look. |
@marc-mabe Many thanks for the feedback. The
I didn't want to completely rule out users handling exceptions however they wanted, but I did imagine that any Service class would add the logger by default - even if it defaulted to a Let me know if there's more to do with |
@Nyholm Many thanks for the feedback and integration tests. I've mocked out the adapter in those now and made sure they all pass 😃 |
You are welcome. I see that your mock preforms better than an actual adapter. When I test this with the redis adapter I fail a few tests. The redis adapter does not preserve datatypes. Consider this test: $item = $this->cache->getItem('key');
$item->set(5); // Integer 5
$this->cache->save($item);
$item = $this->cache->getItem('key');
$this->assertTrue(5 === $item->get(), 'Wrong data type. If we store an int we must get an int back.'); Also, this just crossed my mind. This is not a part of PSR-6 as far as I know. But what if you do like this: $item = $this->cache->getItem('key');
$item->set('foo');
$item->expiresAfter(3600);
$this->cache->save($item);
// 10 minutes later in an other request
$item = $this->cache->getItem('key');
$item->set('bar');
$this->cache->save($item); I'm not too sure how the storage options work. For how long will the item be saved? 3000 more seconds? 3600 seconds? Or infinity? |
Yeah, I noticed that fail with Redis too. Do you happen to know if this is a general issue with how Redis serializes data, or if it's specific to Zend Cache? OT, but it would be useful to provide a mechanism in the integration tests for marking certain tests skipped - maybe be just an associative array of methodName => reason that gets checked at the start of each test. Regarding re-saving an item after TTL has been set: the default TTL configured for the storage would be used in this case. I don't think any implementation could do otherwise reliably - another process may have cleared the cache, it might be unavailable, etc. |
The spec makes a recommendation to log errors or report them but nobody as the calling library can actually handle errors. Also I don't see a difference where your
Redis has no serialize feature, it simply gets requires a string and PHP converts any given value into a string at this point. From spec
That means you have to make sure the adapter (or the serializer plugin) serializes data (reported by |
I've dropped My holidays are over. I no longer have the time to look into the hairy details of Redis serialisation. PR is welcome. Thanks. Edit maybe that's a little short. If the Redis adapter doesn't handle serialising/unserialising data types correctly, isn't that a problem for the Redis adapter? I don't really see why my PRS-6 thingy should be compensating for the underlying adapter getting it wrong. |
Yes, that is possible. It depends how you want to architecture your Pool, Clients and adapters. If you decide to push that problem to the adapters I would recommend doing integration tests with all adapters instead of a mock, just to make sure the adapters work as well. |
public function __construct($key, $value, $isHit) | ||
{ | ||
$this->key = $key; | ||
$this->value = $isHit ? $value : null; |
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.
null is a valid value for PSR-6
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.
Yes, which is why you need to check isHit() - afaik the value should be null if its not a hit.
@kynx the redis adapter doesn't handle it wrong. It does what it suppose to do - sending data to redis in a format that redis supports and that's a string only. If you want more you have to add the serializer plugin. That's because not every one need this support and do serializing even if not required would be an useless overhead. That's how and why zend-cache is designed. So if the underlying adapter doesn't support all requirements from psr-6 this wrapper need to implement it on top. |
@marc-mebe yes I had another l |
Darn phone! Yes, I had another look at this and am completely wrong :( I'm currently putting together integration tests for each adapter. Once that's done I can start working around the differences. |
About skipping tests: php-cache/integration-tests#16 |
|
||
// needed on test expirations | ||
$this->iniUseRequestTime = ini_get('apc.use_request_time'); | ||
ini_set('apc.use_request_time', 0); |
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.
Does apc.use_request_time = 1
break PSR-6 specification? So so an exception should be thrown on instantiating in this case :(
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.
Oh lordy, yes it does. Should've paid more attention to that when I was cut-and-pasting the tests. I've added a check to the constructor and a test.
Looks like CI is going to fail until #64 is in. |
setUp() function in tests should use protected modifier in favor of php-cache/integration-tests#31 |
public function isHit() | ||
{ | ||
$ttl = $this->getTtl(); | ||
return $this->isHit && ($ttl === null || $ttl > 0); |
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.
You should avoid calling getTtl
if the item is already marked as isHit === false
A little bit of If a value can't be @samsonasik - thanks for the heads up. Saw your php-cache/integration-tests#31 - fixed here now too. |
If anyone's interested in Symfony's take on this, check out symfony/symfony#17408 |
@@ -16,10 +16,12 @@ | |||
"php": ">=5.5", | |||
"zendframework/zend-stdlib": "~2.5", | |||
"zendframework/zend-servicemanager": "dev-develop as 2.7.0", | |||
"zendframework/zend-eventmanager": "dev-develop as 2.7.0" | |||
"zendframework/zend-eventmanager": "dev-develop as 2.7.0", |
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.
zendframework/zend-eventmanager ^2.6 || ^3.0 ? /cc @weierophinney
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.
@samsonasik That's not part of this PR - see #64
…e = true and disabled XCache as a result
I've rebased against develop and the tests are passing :) |
The PSR-6 specification requires that the underlying storage support time-to-live (TTL), which is set when the | ||
item is saved. For this reason the following adapters cannot be used: `Dba`, `Filesystem`, `Memory` and `Session`. The | ||
`XCache` adapter calculates TTLs based on the request time, not the time the item is actually persisted, which means | ||
that it also cannot be used. |
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 this is confusing because:
- The filesystem and memory adapter supports TTL but it's based on a stored last-modification-time + runtime TTL setting
- I'll open an issue for the Memory adapter to change this because this should be a simple change and could also improve performance but it's a BC break.
- For the filesystem adapter this would be worst because it would be required to read the file before to know it's expired.
- The XCache adapter is not the only adapter calculating TTLs based on request time. APC/APCu also have this behavior if
apc.use_request_time
which is enabled be default.
EDIT: Uuups you mentioned the APC behavior already in the next paragraph
@kynx it needs rebase. |
@samsonasik Yes, apologies, I've been pretty busy recently. I'll look at doing that this weekend. |
@kynx I did the following changes and merged it now:
Thanks for your work ! |
@marc-mabe Excellent! Thanks for the cleanup, and sorry I faded away. Glad to see this merged! |
This PR address #46, adding a PSR-6 wrapper.
Some key points:
ExceptionLogger
so these can be saved to a PSR-3 compatible logger. Some documentation is probably in order!Happy New Year!