-
Notifications
You must be signed in to change notification settings - Fork 16
Added support for Last-Modified and ETag #8
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
Conversation
$cacheItem->set($data)->expiresAfter($this->config['cache_lifetime'] + $data['expiresAt']); | ||
$this->pool->save($cacheItem); | ||
|
||
return $this->createResponseFromCacheItem($cacheItem); |
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 if the server responds with 304 but there is no cache?
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.
We do now that it is a cache. Or else the If-Modified-Since
and If-None-Match
would not have been added. And correct me if I'm wrong but I don't think the server will answer 304 without those headers in the request.
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, those headers may have been added before. I'll just make sure to pass the response then.
Why do we need cache lifetime? Normally the server tells us how long it should be cached, doesn't it? |
Yes, but we would like to have the possibility to serve an expired response if the server answers 304. |
T0: We make a request. Server responds saying the response is valid until T10. Return response form server |
|
||
$pool->getItem('e3b717d5883a45ef9493d009741f7c64')->shouldBeCalled()->willReturn($item); | ||
$item->isHit()->willReturn(false); | ||
$item->set(['response' => $response, 'body' => $httpBody])->willReturn($item)->shouldBeCalled(); | ||
$item->expiresAfter(60)->willReturn($item)->shouldBeCalled(); | ||
$item->set()->willReturn($item)->shouldBeCalled(); |
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 can't figure out a good way to write this line. I cant specify the exact data since it is dependent on time()
.
Can I say $item->set(<any argument>)->willRetu....
?
I've figured out the tests and I found some bugs. Im done with the code changes and this PR is ready for review. |
@@ -194,11 +231,73 @@ private function getMaxAge(ResponseInterface $response) | |||
private function configureOptions(OptionsResolver $resolver) | |||
{ | |||
$resolver->setDefaults([ | |||
'cache_lifetime' => 2592000, // 30 days |
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.
might be clearer to actually have an arithmetic expression here since it's only executed once
Thank you @GrahamCampbell. I've update the PR according to your suggestions. |
[ci skip] [skip ci]
@@ -15,7 +16,7 @@ class CachePluginSpec extends ObjectBehavior | |||
{ | |||
function let(CacheItemPoolInterface $pool, StreamFactory $streamFactory) | |||
{ | |||
$this->beConstructedWith($pool, $streamFactory, ['default_ttl'=>60]); | |||
$this->beConstructedWith($pool, $streamFactory, ['default_ttl'=>60, 'cache_lifetime'=>1000]); |
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.
odd cs?
$this->beConstructedWith($pool, $streamFactory, ['default_ttl'=>60, 'cache_lifetime'=>1000]); | ||
$this->beConstructedWith($pool, $streamFactory, [ | ||
'default_ttl' => 60, | ||
'cache_lifetime'=>1000 |
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.
missing spaces?
} | ||
} | ||
|
||
return; |
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.
don't need this statement?
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.
See #8 (comment)
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.
yeh, i replied there
$cacheItem | ||
->expiresAfter($this->config['cache_lifetime'] + $maxAge) | ||
->set([ | ||
'response' => $response, |
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.
is this one level not enough indented?
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.
Thank you. But shouldn't StyleCi pick this up?
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.
Symfony has no rules about indentation like this I think?
Looks good. I've not physically tested this in the real world yet though. |
$maxAge = $this->getMaxAge($response); | ||
$currentTime = time(); | ||
$cacheItem | ||
->expiresAfter($this->config['cache_lifetime'] + $maxAge) |
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.
Why are we doing this please?
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.
We would like to serve Responses that the server once said should expire.
See #8 (comment)
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.
when doing cache validation, we keep outdated caches and send If-Modified-Since / If-None-Match requests to the server to check if the cache is ok to be used. we might add some comment in the code though, to make it clear.
went over the code, looks good to me. for a moment i was wondering about stale-while-validate but this is just content validation and not advanced proxy operations. in async mode we theoretically could use stale-while-validate to return the expired response and re-fetch to our local cache. but this has nothing to do with this PR and anyways seems like a bad use case - one should use a dedicated caching proxy for such things, not implement this on client side. |
TODO:
|
We use issets. This PR is ready to be merged |
Thanks, will tag a release soon. |
Awesome. Thank you for all the reviews and feedback. |
What's in this PR?
We should allow the server to answer 304 which allows us to use a response in the cache.
The BC break here is that all existing items in the cache will be invalid. Is that an issue? It is a cache and not a storage.
I introduced a new config parameter
cache_lifetime
that says how long the item should be in cache without it being used.I did also add a few parameters to the array we store in the cache such as
expiresAt
,createdAt
,etag
.To Do