Skip to content
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

getItemsByTag(tagname) does not returns all items with given tag name though item is saved with same tag name.. #719

Closed
msinghgithub opened this issue Jan 13, 2020 · 3 comments

Comments

@msinghgithub
Copy link

Configuration

  • PhpFastCache version: "2.0.4"
  • PhpFastCache API version: "7.1.0"
  • PHP version: "7.3.9"
  • Operating system: "Windows 8.1 "

Describe the bug

getItemsByTag(tagname) seems not working as expected. I have to delete key matching all keys with prefix eg. 'cachekey_'. For this purpose I used getItemsByTag(tagname) to fetch all items with shared tag name and delete matched keys. But it is not returing all cached keys with shared tag ''. However, haskey(key), $item->get() returns data.

To Reproduce
Steps to reproduce the behavior:
Save multiple items with key prefix 'cachekey_' eg. 'cachekey_01', 'cachekey_022', 'cachekey_033', 'cachekey_014', 'cachekey_305', 'cachekey_ffg0' etc.
Save these items with a shared tag in my case '' tagname is used. I tried with static tagname ('pfc') but does not help.
Now list all items stored with tagname '' using getItemsByTag('') method. It should return all keys but unfortunately it doesnot returns all keys. eg. it returns all except 'cachekey_014'. However, haskey('cachekey_014'), $item->get() returns data.

Expected behavior
getItemsByTag('') should returns all keys sharing the tagname ''. So that i can check for partially matched key and delete the matched keys.

Current behavior
All items that share the shared tags are removed only if it is listed by getItemsByTag(''). But few items are not listed. Due to this reason i could not delete key to recreate key with fresh data and showing stale data.

@Geolim4
Copy link
Member

Geolim4 commented Jan 13, 2020

Hello,

I'm unable to reproduce this bug and this feature is hardly-tested:
https://github.com/PHPSocialNetwork/phpfastcache/blob/master/tests/ItemTags.test.php

As you can see, the test above is well-testing the tags feature so I'm not explaining the bug you're describing.

Can you give me a test script that reproduce this bug ?

Cheers,
Georges

@Geolim4 Geolim4 self-assigned this Jan 13, 2020
@Geolim4 Geolim4 added the 7.1 label Jan 13, 2020
@msinghgithub
Copy link
Author

I have created two methods set_data for saving items and delete_key_by_prefix method to delete partially matched keys.

//set item method
public function set_data($key, $value, $expiry_time = '') {
$this->_cache_instance->detachAllItems();
$cache_item = $this->_cache_instance->getItem($key);
if (empty($expiry_time)) $expiry_time = $this->_expire_date;
$cache_item->addtag("");
$cache_item->set($value);
$cache_item->expiresAfter($expiry_time);
$this->_cache_instance->save($cache_item);
}
//Delete key by prefix
public function delete_key_by_prefix($prefixes = array(), $encode_key = false) {
if (!$this->_cache_server_exists) return 'Cache server connection failed.';

    if (is_array($prefixes)) {
        $prefixes = array_unique($prefixes);
    }

   
    $list = array();
    $fetch_all_keys = $this->_cache_instance->getItemsByTag("");
    $clearFlag = null;
    foreach ($fetch_all_keys as $key=>$value) {
        $clearFlag = false;
        if (is_array($prefixes)) {  
            foreach ($prefixes as $prefix) {
                $prefix = ($encode_key) ? $this->get_key($prefix, '', true) : trim($prefix);
                $clearFlag = $clearFlag || preg_match('/^' . preg_quote($prefix, '/i') . '/', $key);
            }
        } else {
            $prefix = ($encode_key) ? $this->get_key($prefix, '', true) : trim($prefix);
            $clearFlag = $clearFlag || preg_match('/^' . preg_quote($prefix, '/i') . '/', $key);
                                                  
        }

        // Clear cache
        if ($clearFlag) {
            $list[] = $key; 
            $this->delete_key($key);                
        }
    }

    if (empty($list)) return 'Key not found.';
    else {
        //$deleted_key_list = implode(',',$list);
    } return 'Keys Deleted.';// . $deleted_key_list;
    
}

Please note this issue is not always replicated but when concurrent users start access webserver then it is replicated randomly. So if method to list all available keys ie from any tags it would be of great help.

Thanks in advance.

@Geolim4
Copy link
Member

Geolim4 commented Jan 14, 2020

getItemsByTag('') is not supposed to return any keys, this behaviour will be fixed soon and throw an exception. This is not intended to be a feature for performances reasons. This could work with dozen of keys, maybe hundred, but this will kill the php memory if you attempt to load more cache item.

Remember that for obvious performances reasons YOU SHOULD NOT load all keys from cache at all, this is the reason why the PSRs did not specified such behavior.

Sorry :)

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

No branches or pull requests

2 participants