Skip to content

[WIP][HttpKernel] PSR6 Store for HttpCache #20061

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

Closed

Conversation

jakzal
Copy link
Contributor

@jakzal jakzal commented Sep 27, 2016

Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets -
License MIT
Doc PR not yet

This is a WIP PR to get early feedback. I'd love to get this in for 3.2.

{
if (!$response->headers->has('X-Content-Digest')) {
$contentDigest = $this->generateContentDigest($response);
$item = $this->cacheBackend->getItem($contentDigest);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make this a guard clause instead. Please note that it should be @return string|null

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I should create a CacheItem instead. No need to query the backend as we're going to overwrite the value anyway (if it's there).

use Symfony\Component\HttpFoundation\Response;

class Psr6Store implements StoreInterface
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to not make it final?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. Good idea.

/**
* @var CacheItemPoolInterface
*/
private $cacheBackend;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For being not in the Cache namespace, i'd favor $cachePool.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed for consistency 👍

@jakzal jakzal force-pushed the http-kernel/psr6-http-cache-store branch from d0ee060 to 1ed4431 Compare September 27, 2016 10:21
@linaori
Copy link
Contributor

linaori commented Sep 27, 2016

@jakzal this ticket is probably explaining the causation? #4871

@jakzal
Copy link
Contributor Author

jakzal commented Sep 27, 2016

@iltar could be fixed by this PR indeed (expiration will be easier with backends like redis), but I was more thinking of making it more "small-website-prod-ready" (see #19705).

@jakzal jakzal force-pushed the http-kernel/psr6-http-cache-store branch from 1ed4431 to 8aac80d Compare September 27, 2016 10:26
@linaori
Copy link
Contributor

linaori commented Sep 27, 2016

@jakzal yeah saw that issue as well when looking for the one mentioned. While this is not the best to use for production servers, it's a nice way to get started if you don't (yet) have a proper caching layer. I think this is a nice feature to have.

@jakzal jakzal force-pushed the http-kernel/psr6-http-cache-store branch 2 times, most recently from 7e548bb to 479b3f2 Compare September 27, 2016 13:04
@jakzal jakzal force-pushed the http-kernel/psr6-http-cache-store branch from 479b3f2 to 8a4c89b Compare September 27, 2016 14:21
Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a good start :) Would it make sense to make an AbstractStorage to share a few things with other storages implems?

final class Psr6Store implements StoreInterface
{
/**
* @var CacheItemPoolInterface
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed, already hinted in the constructor

private $cachePool;

/**
* List of locks acquired by the current process.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure this adds value

/**
* List of locks acquired by the current process.
*
* @var array
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nor that

private $locks = array();

/**
* @param CacheItemPoolInterface $cachePool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

already in the constructor

}

/**
* Locates a cached Response for the Request provided.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{@inheritdoc}

}

/**
* Writes a cache entry to the store for the given Request and Response.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{@inheritdoc}

$headers = $response->headers->all();
unset($headers['age']);

$this->save($key, serialize(array(array($request->headers->all(), $headers))));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

serializing is already done by the cache pool

}

/**
* Invalidates all cache entries that match the request.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{@inheritdoc}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(same below :) )

return true;
}

return $this->cachePool->hasItem($this->getLockKey($request));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use $lockKey

*
* @return CacheItem
*/
private function createCacheItem($key, $value, $isHit = false)
Copy link
Member

@nicolas-grekas nicolas-grekas Sep 28, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes the implementation work only with Symfony's Cache components: cache items aren't interoperable.
You must get the item from the pool first (and maybe keep this as an optimization when Symfony Cache is used, another idea being to keep track of fetched items in this storage object to use them here)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kind of feedback i wanted to get (ignore comments etc, i left them there for my reference until I'm done and replace them with inheritdoc) ;)

You must get the item from the pool first

I did it first, perhaps I tried to optimise too early and replaced a call to pool with this. I'll revert back. Once it's all working we can run tests and see if it needs improving.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having the optimization is OK if you keep the non-optimized version for other pools

@jakzal
Copy link
Contributor Author

jakzal commented Sep 28, 2016

Would it make sense to make an AbstractStorage to share a few things with other storages implems?

I thought about it, but the current implementation is very coupled to the filesystem. I'm currently mirroring the behaviour, but the current implementation is optimised for the filesystem. I expect the psr6 implementation diverge eventually to be optimised for the cache pool.

I'll try this approach nevertheless, to see which one makes more sense.

@fabpot
Copy link
Member

fabpot commented Sep 28, 2016

Just for the record, I'm very skeptical about this one. We explicitly tied the HTTP cache to the filesystem.

@jakzal
Copy link
Contributor Author

jakzal commented Sep 28, 2016

@fabpot no worries. If it's rejected here, I'll create a separate library (so work won't be wasted).

@nicolas-grekas nicolas-grekas added this to the 3.x milestone Dec 6, 2016
@Toflar
Copy link
Contributor

Toflar commented Mar 30, 2017

Now that there's a Lock component, do things get easier? @jakzal do you plan to continue the work on this?

@Toflar
Copy link
Contributor

Toflar commented Apr 7, 2017

FYI: I added a PR to the fork of @jakzal to push this further: jakzal#2
I was not sure whether I should just open a new PR because I actually like working together on something so I figured I'd just PR against the PR 😄

@Toflar
Copy link
Contributor

Toflar commented Apr 24, 2017

@jakzal any feedback here? Even if it's just a "sorry, no time, please open a new PR"? 😄

@fabpot
Copy link
Member

fabpot commented Jul 6, 2017

I'm closing this one as I think this is a bad idea for several reasons:

  • Using a filesystem allows for opcache to make the cache very effective;
  • The cache contains some PHP (when using ESI for instance) and storing PHP in anything else than a filesystem would mean eval()ing strings coming from Redis/Memcache/...,
  • HttpCache is triggered very early and does not have access to the container or anything else really. And it should stay that way to be efficient.

So, for these reasons, it won't be in Symfony core.

@fabpot fabpot closed this Jul 6, 2017
@jakzal jakzal deleted the http-kernel/psr6-http-cache-store branch September 26, 2017 10:42
@Toflar
Copy link
Contributor

Toflar commented Dec 1, 2017

Leaving it here for people looking for a solution without it being in Symfony core: https://packagist.org/packages/toflar/psr6-symfony-http-cache-store

@dunglas
Copy link
Member

dunglas commented Feb 8, 2018

Relying on PSR-6 has a nice side-effect: the ability to use cache tags (see api-platform/core#1689). Is supporting cache tags something we may want in core?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants