Coder Social home page Coder Social logo

issues's People

Contributors

cryptiklemur avatar gitter-badger avatar nyholm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

issues's Issues

Update the Readme

We need to update the readme with a link to the new issue tracker repo and also to be coherent with the Redis adapter. The composer.json file does also need an update. We need to set the homepage to http://www.php-cache.com.

This is a list of repositories that need to be updated:

  • Apc
  • Apcu
  • Array
  • Doctrine
  • Filesystem
  • Memcache
  • Memcaced
  • MongoDB
  • Predis
  • Redis
  • Void
  • Chain
  • AdapterBundle
  • Adapter common
  • CacheBundle
  • Doctrine Bridge
  • Hierarchical cache
  • Integration tets
  • Session handler
  • Tagglable cache

Planned Features

This is a list of planned features:

  • Logging - Log all cache transactions.
  • Validation - It uses a cache from Symfony\Component\Validator\Mapping\Cache\CacheInterface
  • Http - Instead of using disk, one maybe would like to use Redis for HttpCache
  • Serializer - It uses a doctrine cache
  • Annotation - It uses a doctrine cache
  • Templating - This is just a string path to where templates should be stored
  • Twig_CacheInterface

For each of these, investigate if it is a good idea to use a cache service.

From @Nyholm:

I added Twig_CacheInterface to the list. Reference: https://www.reddit.com/r/PHP/comments/413hpc/as_an_experiment_i_wrote_two_alternative/

Possible tagging api issues

From @andrerom:

Looking at this, I see there might be an issue here, depending on what the intention is here.

Current API

Cache tagging in the FOSHttpCache and Drupal 8 sense, is tags that you typically don't know about when requesting the item, you only know it once the item, or it's corresponding entity in database is loaded.

Example would be a cache item representing entity with id 40 of type=article with author id=10, then key might be 'entity:40' and tags would be ['type' => 'article', 'author', 10], allowing you to invalidate/expire all items tagged with either type article, or author 10 later on when something changes to them, including item 'entity:40'.

Further examples can be found in Drupal 8 API doc: https://api.drupal.org/api/drupal/core%21core.api.php/group/cache/8

Implementation of such approach

So afaik no cache backends supports tagging natively, I thought for a while Redis did, but can't find anything on that atm, pity.

For the items we can simply store tags inside same cache, ala ['value' => (...), 'tags' => [..]].

For invalidation we'll also need the reverse relation somewhat given we can't walk/query the cache.

Most likely the most performant and secure approach is to actually insert all tags to item key maps into a database*, this is what is done in D8 and currently also in progress in FOSHttpCache, at least I can't seem to avoid hitting the following issues when trying to look for a way to avoid that:

A. If we opt of storing tags separately where key is tag name and value is list of items tagged with it, then:

  • Given most cache backends tend to drop items at any point if it starts to fill up some of it's cache blocks => if the tags to items map is wiped, effectively we don't know which items should be invalidated anymore.
  • Storages like memcache does not have a notion of arrays, can use strings and append, but question is when you'll hit limits on that
  • When clearing by tag we would need to be able to do a blocking read and replace/delete to be somewhat atomic on the tag itself
    • Once you have the item keys, a multi set / delete can wipe out or expire all items

B. If we opt for just handling tags using expiry (key is tag and value is expiry time), then:

  • same as first cache tag being wiped issue above
  • we now need to do several reads, once we have a cache item, if it has tags we will need to do a multi get to get expiry time stamp for all relevant tags => As I'm personally keen on avoiding several round trips to cache server, this is thus most likely not an option

In database on the other side, it is only read on invalidation, and only written to on save calls when item has tags.

Allow using DSN for connections

Allow using DSN for connections on drivers like Redis and Mongo

redis://localhost:6379
mongodb://user:pass@localhost:27107/

Create tests for issue: Clean up of DateTime expiration

Having a look at the CacheItem implementation.

The type hint on the getExpiration method should probably be DateTimeInterface (on CacheItem and HasExpirationDateInterface) as I believe the constructor allows these objects.

Also, all date time objects should be immediately cloned once they have been passed to __construct or expiresAt. Otherwise later changes to the object will change the expiration of the cache item.

A possible solution to the getExpirationDate problem

From @AndrewCarterUK

I'm not sure if you will want to go down this route - but here is a proof of concept approach to handling expiresAt and expiresAfter without memory leaks or supplementing the PSR-6 interface with additional methods:

<?php

class Communicator
{
    private $store;

    public function __construct()
    {
        $this->store = array();
    }

    public function set($key, $expiration)
    {
        $this->store[$key] = $expiration;
    }

    public function get($key)
    {
        return isset($this->store[$key]) ? $this->store[$key] : null;
    }

    public function clear($key)
    {
        unset($this->store[$key]);
    }
}

class Item
{
    private $key;
    private $communicator;

    public function __construct($key, Communicator $communicator)
    {
        $this->key = $key;
        $this->communicator = $communicator;
    }

    public function __destruct()
    {
        echo 'Removing key from communicator...' . PHP_EOL;
        $this->communicator->clear($this->key);
    }

    public function getKey()
    {
        return $this->key;
    }

    public function setExpiration($expiration)
    {
        $this->communicator->set($this->key, $expiration);
    }
}

class Pool
{
    private $communicator;

    public function __construct()
    {
        $this->communicator = new Communicator();
    }

    public function getItem($key)
    {
        return new Item($key, $this->communicator);
    }

    public function save(Item $item)
    {
        $expiration = $this->communicator->get($item->getKey());
        echo 'Expiration: ' . $expiration . PHP_EOL;
    }
}

function test() {
    $pool = new Pool();
    $item = $pool->getItem('foo');
    $item->setExpiration('bar');
    $pool->save($item);
}

test();

echo 'Done' . PHP_EOL;

Output:

Expiration: bar
Removing key from communicator...
Done

https://3v4l.org/K1ceR

appendListItem race condition

As far as I can see if two or more processes are using a TaggableCache appendListItem can cause race conditions.

Whenever an item is added to the cache and saveTags is called from the trait this uses appendListItem to add keys the the cached array of keys for that tag.

  1. process A saves an item and thus gets the array of tags to update
  2. process B saves and item and also get the array of tags to update
  3. process A saves the array
  4. process B saves the array
  5. The key index now only includes the tagged key form process B and not process A

This could be solved with some kind of locks being used?

Interface to typehint against

When I require a cache pool that has taggs in my app I would like to type hint against something that allow me to use tag but also include the CacheItemPoolInterface::save.

I can't use TaggablePoolInterface since it does not have a save function. Is it a good solution to create an interface that extends both TaggablePoolInterface and CacheItemPoolInterface and make sure adapters implement the new interface?

Invalid key Uncaught PHP Exception

Hi, I am getting what appears to be random Critical error messages from time to time on our live environment such as this (domain name replaced):

request.CRITICAL: Uncaught PHP Exception Cache\Adapter\Common\Exception\InvalidArgumentException: "Invalid key: "www.mydomain.co.uk__.https:..maps.google.co.uk.maps__GET__f=q". The key contains one or more characters reserved for future extension: {}()/@:" at /var/www/releases/20160317121445/vendor/cache/adapter-common/src/AbstractCachePool.php line 241 {"exception":"[object](Cache\Adapter\Common\Exception\InvalidArgumentException%28code: 0%29: Invalid key: "www.mydomain.co.uk__.https:..maps.google.co.uk.maps__GET__f=q". The key contains one or more characters reserved for future extension: {}%28%29/@: at /var/www/releases/20160317121445/vendor/cache/adapter-common/src/AbstractCachePool.php:241)"} []

and this:

request.CRITICAL: Uncaught PHP Exception Cache\Adapter\Common\Exception\InvalidArgumentException: "Invalid key: "www.mydomain.co.uk__.index.php__GET__q=user/register". The key contains one or more characters reserved for future extension: {}()/@:" at /var/www/releases/20160317121445/vendor/cache/adapter-common/src/AbstractCachePool.php line 241 {"exception":"[object](Cache\Adapter\Common\Exception\InvalidArgumentException%28code: 0%29: Invalid key: "www.mydomain.co.uk__.index.php__GET__q=user/register". The key contains one or more characters reserved for future extension: {}%28%29/@: at /var/www/releases/20160317121445/vendor/cache/adapter-common/src/AbstractCachePool.php:241)"} []

In the second case it looks like it is because of the forward slash, but I don't know about the first one. More interestingly I don't have an index.php so why is that in there? Is this a bug in the router cache?

Thanks

Update toolbar icons

The Symfony bundle has a toolbar logo that needs to be updated. The new logo is I the documentation repo.

Create Factories for Doctrine Cache

We need Doctrine factories for:

  • Apc
  • Apcu
  • Array
  • Couchbase
  • File
  • Filesystem
  • Memcache
  • Memcached
  • MongoDb
  • PhpFile
  • Predis
  • Redis
  • Riak
  • SQLite3
  • Void
  • WinCache
  • Xcache
  • ZendData

We do not have to do them all. Just do some popular and the once we do not have any adapters for.

Expiration

I noticed a strange behavior. When I use null as argument for expiresAfter, everything is fine. (I use Redis, so the non-expiring SET operation is used.)

$item = $pool->getItem('some key');
$item->set('some value');
$item->expiresAfter(null);
$pool->save($item); // works fine: "SET" "[some key][1]" ...

But when is use 0 as argument for expiresAfter, the NULL value is cached.

$item = $pool->getItem('some key');
$item->set('some value');
$item->expiresAfter(0);
$pool->save($item); // strange: "SET" "[some key][1]" "s:2:\"N;\";"

I think, the problem is, that $item->setExpiresAfter(0) immediately makes the $item->isHit() return false. This is ok, but the no-longer-hit $item is saved anyway. Maybe $pool->save($item) should fail, if false === $item->isHit()?

memcached perf issues ?

Hello everyone,

First, thanks for your work on those different bundles!

I'm currently monitoring my app with newrelic and i can see a 180 ms latency (this an average but it never goes down even after a week) only attributed to memcached which is unlikely to be normal.
Are you aware of any performance issue concerning the memcached bundle ?

Add comment about cache key

The cache key must support spaces (which is not a part of the spec). It must also support the exclamation mark "!".

This should be documented.

Is that still true? Why should it support spaces?

Make sure the examples in the docs does not have any spaces and verify that spaces aren't needed.

Notice: Undefined index: use_tagging

I get the following notice thrown in

Cache\CacheBundle\Factory\DoctrineBridgeFactory

But I’m not sure where to put this in the config to fix it.

Update readme on php-cache/cache

We should explain that the repo is for development only. If they need an adapter they should install the adapter directly. We should also refer users to the website.

Installation Instructions & Requirements

Just above the "framework integration" there should be installation instructions. It should just say that you need to use composer to install an adapter and the reference to the packet's github page

Error Handling

While caching is often an important part of application performance, it should never be a critical part of application functionality. Thus, an error in a cache system SHOULD NOT result in application failure. For that reason Implementing Libraries MUST NOT throw exceptions other than those defined by the interface, and SHOULD trap any errors or exceptions triggered by an underlying data store and not allow them to bubble.

An Implementing Library SHOULD log such errors or otherwise report them to an administrator as appropriate.

Let's make the AbstractPool implement Psr\Log\LoggerAwareInterface and add the setLogger() function. Then do a try catch to fetch every \Exception we can. We should only re-throw our InvalidArgumentException.

Create cache/cache meta project

Hi !

Why not create a meta project that requires all adapaters? This project will contain only a composer.json that would look like this:

{
    "name": "cache/cache",
    "require": {
        "cache/apc-adapter": "^0.1",
        "cache/apcu-adapter": "^0.1",
        "cache/array-adapter": "^0.1",
        "..."
    }
}

Like that, lazy developers (as me) just have to do composer require cache/cache.

Update tagging and adapter common versions

We need to update all our adapters to use cache/adapter-common: ^0.2 and cache/taggable-cache:^0.3. These updates will not be backwards compatible.

  • Apc
  • Apcu
  • Array
  • Doctrine
  • Filesystem
  • Memcache
  • Memcaced
  • MongoDB
  • Predis
  • Redis
  • Void
  • Chain
  • CacheBundle
  • Hierarchical cache

Planned Adapters

Documented that this is only for testing, or fix stale cache + filling up memory issues

From @andrerom

By design this has a high risk of filling up memory, and causing stale data and corresponding issues in applications (the longer application is running the higher risk that some other request/server/process has invalidated items cached here).

Same issue exists in Stash, where similar driver in lib is documented for unit test, but Bundle is exposing option for end users to enable "InMemory" cache without really documenting the issues it can cause.

Possible solutions

A. Clearly documented that this is for testing only, and never use in any doc or examples or bundles or bridges, other then for internal tests.

B. Aim to support in prod where people want performance at own risk, then somewhat fix the issues:

  • Add limit (100?) to avoid filling up memory, clear in first in first out order to recycle items over time
  • Add flag to getItem(s) where application developer can specify that stale data is allowed on a use case by use case basis, pass this argument to adapter and only return items from this array cache if application accepts stale data.

With B this adapter can be somewhat reliably be used with Chain adapter in front of adapter serving the real shared cache pool, at least assuming the developer using api knows his domain well enough to know when he can safely use stale data.

Should the expiration value remain after second save?

Consider this:

// T = 0
$item = $pool->getItem('key');
$item->set('value');
$item->expiresAfter(3600);
$pool->save($item);

// T = 600
$item = $pool->getItem('key');
$item->set('foobar');
$pool->save($item);

For how long is the item still in cache? The way I see it there are three options:

  • A) Until T=3600
  • B) Until T=4200
  • C) Forever since $item->expiresAfter() was never called.

I believe that option A is preferable.

This question has a lot of impact on performance. If C is the right way we do not have to read to the cache before doing a store.

EDIT Correct answer is C

From @Nyholm: The correct answer was C according to the mailing list. We need to write a test for that.

Invalid cache key for doctrine

I get the following error when using doctrine caching and I’m not sure how to change the name of the cache key.

Invalid key: ”MyNameSpace\CoreBundle\Entity\User$CLASSMETADATA”. The key contains one or more characters reserved for future extension: {}()/@:

New Logo

We need a new logo!

Suggestions are open, and welcome!

Document issues/vague specification in PSR-6

@kynx wrote on php-cache/integration-tests#43 (comment)

I think collecting all the places where PSR-6 is a bit vague into one place (maybe a wiki on this repo?) would be a valuable thing. Ultimately it would be for FIG to issue an addendum or whatever - which may take years ;) - but in the meantime it would be a valuable resource for implementers.

I believe this is a good idea. We should document points to explain our interpretation of the methods and functionality in PSR-6.

As I see it we can put the documentation in four places:

  1. A wiki the integration tests.
  2. A wiki on the main repository
  3. As documentation (normal markdown files) on the integration tests repo
  4. A new section on PHP-cache.com

Any thoughts?

Memcached TaggablePoolInterface expected MemcachedCachePool given

When I try to clear the cache using app/console cache:flush all I get the following warning:

Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'Cache\Adapter\Memcached\MemcachedCachePool' does not have a method 'clearTags'

In the following method in Cache\CacheBundle\CommandCacheFlushCommand

private function clearTypedCacheFromService($type, $serviceId)
    {
        /** @type \Psr\Cache\CacheItemPoolInterface $service */
        $service = $this->getContainer()->get($serviceId);
        if ($service instanceof TaggablePoolInterface) {
            return $service->clearTags([$type]);
        } else {
            return $service->clear();
        }
    }

Cache\Adapter\Memcached\MemcachedCachePool does not implement TaggablePoolInterface. However, in Cache\CacheBundle\Command\CacheFlushCommand -> clearTypedCacheFromService() the service IS an instance of TaggablePoolInterface although when I dump $service here I get

Cache\CacheBundle\Cache\RecordingCachePool {#450
-calls: []
-cachePool: Cache\Adapter\Memcached\MemcachedCachePool {#446
-cache: Memcached {#449}
#deferred: []
-keyCache: []
}
}

If I temporarily return $service->clear(); then I can get the cache to clear. However, after returning the code to it's original state and then running my web application, I then get the following:

Argument 1 passed to Cache\CacheBundle\Cache\FixedTaggingCachePool::__construct() must be an instance of Cache\Taggable\TaggablePoolInterface, instance of Cache\Adapter\Memcached\MemcachedCachePool given, called in /***********/vendor/cache/cache-bundle/src/Factory/DoctrineBridgeFactory.php on line 33 and defined', '/*******/vendor/cache/cache-bundle/src/Cache/FixedTaggingCachePool.php', '41', array()) in FixedTaggingCachePool.php line 41

I'm not sure why tagging is a requirement anyway, as I am not using tagging myself.

Add warning for long running requests

@Nyholm

There is an issue here, I don't know if we should bother or not. But what if we start request A and lots of tags will get into the temporary storage. At the same time request B will invalidate all these tags. A will not see that the tags are invalid.

This is only an issue with long running requests. If A takes less than 200 ms as it should, this would not be a problem.

Any thoughts?

@aequasi

A warning should be made about that i think.

Fix integration-tests requirement

Issue: Right now, when we run that script, SessionHandler and Bridge both have the integration-tests requirement, when they don't need it

Also, we could do this:

Update all the libraries so they just require * version or something, and then during the travis build, update them.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.