You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jcs-users@jakarta.apache.org by Amitay Dobo <am...@gmail.com> on 2009/12/28 11:40:29 UTC

Updating a cache item without affecting it's removal from cache by LRU

We use a system which caches resources, but asynchronously updates the cache
contents for each resource on various intervals (so when getting from the
cache you will always have up to date content). Resources in the cache that
are not used should be removed by the cache mechanism, and stopped being
updated.

The problem is, from what we witness, is that both checking if an item is
still in the cache, and by updating its data, JCS  mark it as accessed, and
the LRU Memory prevents it from being purged from the cache.
This can be demonstrated by this test code:

        JCS cache = null;

        try {
            cache = JCS.getInstance("default");
        } catch (CacheException e) {
            e.printStackTrace();
        }

        // Put the first item
        cache.put("key", "data");
        Thread.sleep(1000);

        for (Integer i = 0; i < 1005; i++) {
            // Put and access some other keys in the cache. Since they are
accessed they should be kept
            cache.put("key" + i.toString(), "data");
            cache.get("key" + i.toString());

            // Update the data for the first key. Removing this lines causes
the test to pass with no exception.
            cache.put("key", "dataNew");

        }

        // get the first inserted key, after more items than MaxObjects were
put and accessed.
        String valueAfterWait = (String) cache.get("key");

        System.out.println(cache.getStats());

        if (!(valueAfterWait == null)) {
            throw new RuntimeException("Data should be null. actual value is
" + valueAfterWait);
        }

Cache.ccf:
# DEFAULT CACHE REGION
jcs.default=
jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects=1000
jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache

In the actual code we *DO* need to access the cache for the original key
somehow, to see if there still is a cache for it, other wise we don't want
to re-insert it.
I saw on a similiar discussion (
http://www.mail-archive.com/jcs-users@jakarta.apache.org/msg00783.html) that
there is a getQuiet() method in org.apache.jcs.engine.memory.AbstractMemory
, but It doesn't seem like a good idea to use it, and i want the disk
caching to work well.

To sum it:
* Is there a way to peek at a cache item (or just check if it exists) and
update its data without the item being considered as accessed?

Thanks,
Amitay Dobo

Re: Updating a cache item without affecting it's removal from cache by LRU

Posted by Aaron Smuts <as...@yahoo.com>.
There is no way to merely check to see if JCS contains an item.  This would have to be added to the API.  

Aaron

--- On Tue, 12/29/09, Amitay Dobo <am...@gmail.com> wrote:

> From: Amitay Dobo <am...@gmail.com>
> Subject: Re: Updating a cache item without affecting it's removal from cache  by LRU
> To: "JCS Users List" <jc...@jakarta.apache.org>
> Date: Tuesday, December 29, 2009, 5:32 AM
> It turns out my last post was wrong:
> calling put() with original
> ElementAttributes does cause the lastAccessTime to change
> anyway. What
> happened when I used the event handler, is that the cache
> item was expired
> due to maxLifeSeconds being exceeded, since the createTime
> for the
> attributes are not updates.
> 
> Amitay Dobo
> 
> So, I'm back to square one, with no known way of updating
> the contents of a
> cahed item in the cache (if it exists), without its last
> access time being
> updated. I will try to evaluate alternatives to JCS.
> 
> On Mon, Dec 28, 2009 at 4:49 PM, Amitay Dobo <am...@gmail.com>
> wrote:
> 
> > Thanks for you quick reply, Thomas.
> > I have considered using the CacheEvents mechanism for
> other reaosons, but I
> > don't think it can solve the problem I'm facing.
> Within the event handler, I
> > will still need to use (as far as i know), JCS.put().
> This will cause the
> > cache item to be mark as accessed, and will prevent it
> from being "pushed
> > out" of the cache by items which are actually used.
> > I'll try to rephrase: there are two expirations in the
> system:
> > 1) Content Expiration (application defined per item)
> > 2) Cache Expiration (controlled by JCS, might be a
> result of items pushed
> > out of cache as a result of being LRU).
> >
> > Content expiration should update the content in the
> cache (if the item is
> > still in the cache), but should *not* affect the cache
> expiration.
> >
> > However, working on the a test to confirm that using
> the events does not
> > work (since they use the regular put() method), proved
> me wrong, but not for
> > the reason i suspected. I used the following (rather
> rough) code:
> >         // event handler
> for updating the item with new data.
> >          class
> TestEventHandler implements IElementEventHandler {
> >              JCS
> m_cache;
> >
> >         
>    public TestEventHandler(JCS cache) {
> >             
>    m_cache = cache;
> >             }
> >
> >         
>    @Override
> >         
>    public void
> handleElementEvent(IElementEvent event) {
> >             
>    int eventType = event.getElementEvent();
> >             
>    System.out.println(eventType);
> >             
>    CacheElement element =
> > (CacheElement)((EventObject)event).getSource();
> >
> >             
>    if (eventType ==
> >
> IElementEventHandler.ELEMENT_EVENT_EXCEEDED_MAXLIFE_BACKGROUND)
> {
> >               
>      try {
> >               
>      
>    System.out.println("updating");
> >               
>      
>    m_cache.put(element.getKey(), "newData",
> > element.getElementAttributes());
> >
> >               
>      } catch (CacheException e) {
> >               
>          e.printStackTrace();
> >               
>      }
> >             
>    }
> >
> >             }
> >
> >         }
> >
> > And it worked!
> > I noticed that I use a different JCS.put() overload
> which accepts
> > IElementAttributes.
> > When i changed in the previously submitted code line
> from:
> > cache.put("key", "dataNew");
> > to:
> > cache.put("key", "dataNew", new ElementAttributes());
> > The item seemed to be pushed out of cache (as it
> should). However, it does
> > not seems correct, as the cache element current
> attributes should be kept
> > from the current element (along with the correct last
> access time).
> > using:
> > cache.put("key", "dataNew",
> cache.getElementAttributes("key"));
> > does not work, as it seems getElementAttributes()
> causes updating the last
> > access time.
> >
> > Since we might not use the expiration events (as we
> have our own mechanism
> > for dealing with content updates), can anyone shed
> some light on the
> > subject? Is there a way to get ElementAttributes of a
> cached item without
> > setting its access time?
> >
> >
> >
> > On Mon, Dec 28, 2009 at 12:53 PM, Thomas Vandahl
> <tv...@apache.org>
> wrote:
> >
> >> Amitay Dobo wrote:
> >> > The problem is, from what we witness, is that
> both checking if an item
> >> is
> >> > still in the cache, and by updating its data,
> JCS  mark it as accessed,
> >> and
> >> > the LRU Memory prevents it from being purged
> from the cache.
> >>
> >> You may have a look at the CacheEvent mechanisms
> available in JCS
> >> (http://jakarta.apache.org/jcs/ElementEventHandling.html).
> So you can
> >> re-insert the item when an expired event occurs,
> for example, and save
> >> unnecessary checks and background operations.
> >>
> >> > * Is there a way to peek at a cache item (or
> just check if it exists)
> >> and
> >> > update its data without the item being
> considered as accessed?
> >>
> >> I used cache groups for this.
> JCS.getGroupKeys(java.lang.String group)
> >> gives you a Set of the keys in a given group.
> >>
> >> Bye, Thomas.
> >>
> >>
> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: jcs-users-unsubscribe@jakarta.apache.org
> >> For additional commands, e-mail: jcs-users-help@jakarta.apache.org
> >>
> >>
> >
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: jcs-users-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jcs-users-help@jakarta.apache.org


Re: Updating a cache item without affecting it's removal from cache by LRU

Posted by Amitay Dobo <am...@gmail.com>.
It turns out my last post was wrong: calling put() with original
ElementAttributes does cause the lastAccessTime to change anyway. What
happened when I used the event handler, is that the cache item was expired
due to maxLifeSeconds being exceeded, since the createTime for the
attributes are not updates.

Amitay Dobo

So, I'm back to square one, with no known way of updating the contents of a
cahed item in the cache (if it exists), without its last access time being
updated. I will try to evaluate alternatives to JCS.

On Mon, Dec 28, 2009 at 4:49 PM, Amitay Dobo <am...@gmail.com> wrote:

> Thanks for you quick reply, Thomas.
> I have considered using the CacheEvents mechanism for other reaosons, but I
> don't think it can solve the problem I'm facing. Within the event handler, I
> will still need to use (as far as i know), JCS.put(). This will cause the
> cache item to be mark as accessed, and will prevent it from being "pushed
> out" of the cache by items which are actually used.
> I'll try to rephrase: there are two expirations in the system:
> 1) Content Expiration (application defined per item)
> 2) Cache Expiration (controlled by JCS, might be a result of items pushed
> out of cache as a result of being LRU).
>
> Content expiration should update the content in the cache (if the item is
> still in the cache), but should *not* affect the cache expiration.
>
> However, working on the a test to confirm that using the events does not
> work (since they use the regular put() method), proved me wrong, but not for
> the reason i suspected. I used the following (rather rough) code:
>         // event handler for updating the item with new data.
>          class TestEventHandler implements IElementEventHandler {
>              JCS m_cache;
>
>             public TestEventHandler(JCS cache) {
>                 m_cache = cache;
>             }
>
>             @Override
>             public void handleElementEvent(IElementEvent event) {
>                 int eventType = event.getElementEvent();
>                 System.out.println(eventType);
>                 CacheElement element =
> (CacheElement)((EventObject)event).getSource();
>
>                 if (eventType ==
> IElementEventHandler.ELEMENT_EVENT_EXCEEDED_MAXLIFE_BACKGROUND) {
>                     try {
>                         System.out.println("updating");
>                         m_cache.put(element.getKey(), "newData",
> element.getElementAttributes());
>
>                     } catch (CacheException e) {
>                         e.printStackTrace();
>                     }
>                 }
>
>             }
>
>         }
>
> And it worked!
> I noticed that I use a different JCS.put() overload which accepts
> IElementAttributes.
> When i changed in the previously submitted code line from:
> cache.put("key", "dataNew");
> to:
> cache.put("key", "dataNew", new ElementAttributes());
> The item seemed to be pushed out of cache (as it should). However, it does
> not seems correct, as the cache element current attributes should be kept
> from the current element (along with the correct last access time).
> using:
> cache.put("key", "dataNew", cache.getElementAttributes("key"));
> does not work, as it seems getElementAttributes() causes updating the last
> access time.
>
> Since we might not use the expiration events (as we have our own mechanism
> for dealing with content updates), can anyone shed some light on the
> subject? Is there a way to get ElementAttributes of a cached item without
> setting its access time?
>
>
>
> On Mon, Dec 28, 2009 at 12:53 PM, Thomas Vandahl <tv...@apache.org> wrote:
>
>> Amitay Dobo wrote:
>> > The problem is, from what we witness, is that both checking if an item
>> is
>> > still in the cache, and by updating its data, JCS  mark it as accessed,
>> and
>> > the LRU Memory prevents it from being purged from the cache.
>>
>> You may have a look at the CacheEvent mechanisms available in JCS
>> (http://jakarta.apache.org/jcs/ElementEventHandling.html). So you can
>> re-insert the item when an expired event occurs, for example, and save
>> unnecessary checks and background operations.
>>
>> > * Is there a way to peek at a cache item (or just check if it exists)
>> and
>> > update its data without the item being considered as accessed?
>>
>> I used cache groups for this. JCS.getGroupKeys(java.lang.String group)
>> gives you a Set of the keys in a given group.
>>
>> Bye, Thomas.
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: jcs-users-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: jcs-users-help@jakarta.apache.org
>>
>>
>

Re: Updating a cache item without affecting it's removal from cache by LRU

Posted by Amitay Dobo <am...@gmail.com>.
Thanks for you quick reply, Thomas.
I have considered using the CacheEvents mechanism for other reaosons, but I
don't think it can solve the problem I'm facing. Within the event handler, I
will still need to use (as far as i know), JCS.put(). This will cause the
cache item to be mark as accessed, and will prevent it from being "pushed
out" of the cache by items which are actually used.
I'll try to rephrase: there are two expirations in the system:
1) Content Expiration (application defined per item)
2) Cache Expiration (controlled by JCS, might be a result of items pushed
out of cache as a result of being LRU).

Content expiration should update the content in the cache (if the item is
still in the cache), but should *not* affect the cache expiration.

However, working on the a test to confirm that using the events does not
work (since they use the regular put() method), proved me wrong, but not for
the reason i suspected. I used the following (rather rough) code:
        // event handler for updating the item with new data.
         class TestEventHandler implements IElementEventHandler {
             JCS m_cache;

            public TestEventHandler(JCS cache) {
                m_cache = cache;
            }

            @Override
            public void handleElementEvent(IElementEvent event) {
                int eventType = event.getElementEvent();
                System.out.println(eventType);
                CacheElement element =
(CacheElement)((EventObject)event).getSource();

                if (eventType ==
IElementEventHandler.ELEMENT_EVENT_EXCEEDED_MAXLIFE_BACKGROUND) {
                    try {
                        System.out.println("updating");
                        m_cache.put(element.getKey(), "newData",
element.getElementAttributes());
                    } catch (CacheException e) {
                        e.printStackTrace();
                    }
                }

            }

        }

And it worked!
I noticed that I use a different JCS.put() overload which accepts
IElementAttributes.
When i changed in the previously submitted code line from:
cache.put("key", "dataNew");
to:
cache.put("key", "dataNew", new ElementAttributes());
The item seemed to be pushed out of cache (as it should). However, it does
not seems correct, as the cache element current attributes should be kept
from the current element (along with the correct last access time).
using:
cache.put("key", "dataNew", cache.getElementAttributes("key"));
does not work, as it seems getElementAttributes() causes updating the last
access time.

Since we might not use the expiration events (as we have our own mechanism
for dealing with content updates), can anyone shed some light on the
subject? Is there a way to get ElementAttributes of a cached item without
setting its access time?


On Mon, Dec 28, 2009 at 12:53 PM, Thomas Vandahl <tv...@apache.org> wrote:

> Amitay Dobo wrote:
> > The problem is, from what we witness, is that both checking if an item is
> > still in the cache, and by updating its data, JCS  mark it as accessed,
> and
> > the LRU Memory prevents it from being purged from the cache.
>
> You may have a look at the CacheEvent mechanisms available in JCS
> (http://jakarta.apache.org/jcs/ElementEventHandling.html). So you can
> re-insert the item when an expired event occurs, for example, and save
> unnecessary checks and background operations.
>
> > * Is there a way to peek at a cache item (or just check if it exists) and
> > update its data without the item being considered as accessed?
>
> I used cache groups for this. JCS.getGroupKeys(java.lang.String group)
> gives you a Set of the keys in a given group.
>
> Bye, Thomas.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: jcs-users-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: jcs-users-help@jakarta.apache.org
>
>

Re: Updating a cache item without affecting it's removal from cache by LRU

Posted by Thomas Vandahl <tv...@apache.org>.
Amitay Dobo wrote:
> The problem is, from what we witness, is that both checking if an item is
> still in the cache, and by updating its data, JCS  mark it as accessed, and
> the LRU Memory prevents it from being purged from the cache.

You may have a look at the CacheEvent mechanisms available in JCS
(http://jakarta.apache.org/jcs/ElementEventHandling.html). So you can
re-insert the item when an expired event occurs, for example, and save
unnecessary checks and background operations.

> * Is there a way to peek at a cache item (or just check if it exists) and
> update its data without the item being considered as accessed?

I used cache groups for this. JCS.getGroupKeys(java.lang.String group)
gives you a Set of the keys in a given group.

Bye, Thomas.

---------------------------------------------------------------------
To unsubscribe, e-mail: jcs-users-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jcs-users-help@jakarta.apache.org