jbosscache-dev@lists.jboss.org
by Mail Administrator
Dear user jbosscache-dev(a)lists.jboss.org, administration of lists.jboss.org would like to inform you that,
We have detected that your e-mail account was used to send a huge amount of unsolicited email messages during this week.
Most likely your computer was infected by a recent virus and now runs a trojaned proxy server.
We recommend you to follow our instructions in order to keep your computer safe.
Sincerely yours,
lists.jboss.org support team.
15 years, 8 months
Re: lock() and unlock() methods ?
by Brian Stansberry
Bela Ban wrote:
> Let's hear from others before we put anything on the roadmap.
>
> I recall Brian mentioning his need for locks, but AFAIR not in
> conjunction with JBossCache but with Farming...
>
I have two use cases in my mind that involve something like cluster-wide
locking. I don't think either matches what's being discussed here or is
a real good general feature for JBC:
1) Clustered deployments. Not JBC-related.
2) Session ownership. There it's not a lock + try + dostuff + finally +
unlock thing. It's more one node takes possession of the token for a
session via a cluster wide call, and thereafter locks locally when using
the session. It doesn't "unlock" via any cluster-wide call. On failover
another nodes takes possession of the token. If the node holding the
token is still alive and using it, it doesn't release the token until it
is done.
>
> Manik Surtani wrote:
>>
>> On 20 Mar 2009, at 08:36, Bela Ban wrote:
>>
>>> I know, but what he wants to do is
>>> #1 Read a value
>>> #2 Based on that value (which I assume shouldn't change from
>>> underneath him), do some computations
>>> #3 Write the changed value back
>>>
>>> I guess the problem is that some other TX could change the value and
>>> have the later TX fail & roll back...
>>>
>>> AFAIR we don't have Cache.lock(K) and unlock(K), do we ? If so, would
>>> it make sense to add them ? And then we'd have to think about
>>
>> We don't at the moment. Adding them is simple, making them
>> scale/perform well is hard. :-)
>>
>> It would be a simple LockCommand which is broadcast (anycast?) via
>> RPC. If it doesn't return (in time), assume we don't have the lock
>> and throw a timeout exception. This call would *have* to be
>> synchronous though, it can't work in an async manner.
>>
>>> * how this fares with TX-incurred locking
>>
>> It would hold the locks until unlock() is called, or a tx completes,
>> whichever happens first, I guess.
>>
>>>
>>> * what type of locks lock() acquires
>>
>> Write locks. We don't have such a thing as read locks in Horizon or
>> even JBC3's MVCC.
>>
>>> WDYT ?
>>
>> I don't mind putting it on the Horizon roadmap, but I can't promise
>> when it would get done - its just a case of prioritising stuff. If
>> another resource is looking unlikely/delayed we have a lot of stuff on
>> our plate... :-(
>>
>>>
>>>
>>>
>>> Manik Surtani wrote:
>>>> No, a tx +RR is still optimistic cluster-wide in that it is only on
>>>> tx commit (tx prepare, actually) that remote locks are acquired.
>>>>
>>>> This essentially is a distributed lock.
>>>>
>>>>
>>>> On 20 Mar 2009, at 07:34, Bela Ban wrote:
>>>>
>>>>> Do we have a hard-lock mechanism like the one below for Coherence ?
>>>>>
>>>>> Would a TX with RR be the equivalent ?
>>>>>
>>>>>
>>>>> -------- Original Message --------
>>>>> Subject: RE: [javagroups-users] Distributed Lock Manager Listener
>>>>> Date: Thu, 19 Mar 2009 12:03:42 -0500
>>>>> From: Urciolo, Kevin J (IS) <Kevin.Urciolo(a)ngc.com>
>>>>> To: Bela Ban <belaban(a)yahoo.com>
>>>>> CC: <javagroups-users(a)lists.sourceforge.net>
>>>>> References:
>>>>> <0E36CF63779A934D876C5E7FD29E74EB01FA4FFC(a)XMBIL123.northgrum.com>
>>>>> <49C206DC.8030608(a)yahoo.com>
>>>>>
>>>>>
>>>>>
>>>>> I am trying to accomplish the locking mechanism as shown in this
>>>>> example
>>>>> from Coherence. I need to execute a piece of code that is mutually
>>>>> exclusive throughout the group.
>>>>>
>>>>> I looked at the VotingAdapter. I seemed to get the notifications
>>>>> before
>>>>> the lock was released, but caused the thread waiting for the lock
>>>>> to try
>>>>> again too early and get another LockNotGrantedException.
>>>>>
>>>>> NamedCache cache = CacheFactory.getCache("dist-cache");
>>>>> Object key = "example_key";
>>>>> cache.lock(key, -1);
>>>>> try
>>>>> {
>>>>> Object value = cache.get(key);
>>>>> // application logic
>>>>> cache.put(key, value);
>>>>> }
>>>>> finally
>>>>> {
>>>>> // Always unlock in a "finally" block
>>>>> // to ensure that uncaught exceptions
>>>>> // don't leave data locked
>>>>> cache.unlock(key);
>>>>> }
>>>>> -----Original Message-----
>>>>> From: Bela Ban [mailto:belaban@yahoo.com] Sent: Thursday, March 19,
>>>>> 2009 4:48 AM
>>>>> To: Urciolo, Kevin J (IS)
>>>>> Cc: javagroups-users(a)lists.sourceforge.net
>>>>> Subject: Re: [javagroups-users] Distributed Lock Manager Listener
>>>>>
>>>>>
>>>>>
>>>>> Urciolo, Kevin J (IS) wrote:
>>>>>> I would like to use the distributed lock manager. However, I would
>>>>>> like my components to block until a lock is available instead of
>>>>>> getting an exception thrown.
>>>>>
>>>>> What if the lock cannot be granted ? There's a LockNotGrantedException
>>>>> when this happens. I also assume you would not want to wait forever
>>>>> if a
>>>>> lock is held by a different owner.
>>>>>
>>>>>> Is this possible? If not, is it possible to listen for events on
>>>>>> locks
>>>>>
>>>>>> so I can implement my own listener mechanism?
>>>>>
>>>>> There's a VotingAdapter class which implements
>>>>> VoteResponseProcessor. This class has callbacks, but of course you
>>>>> could also write your own
>>>>> implementation
>>>>>
>>>>> --
>>>>> Bela Ban
>>>>> Lead JGroups / Clustering Team
>>>>> JBoss - a division of Red Hat
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Bela Ban
>>>>> Lead JGroups / Clustering Team
>>>>> JBoss - a division of Red Hat
>>>>>
>>>>>
>>>>
>>>> --
>>>> Manik Surtani
>>>> Lead, JBoss Cache
>>>> http://www.jbosscache.org
>>>> manik(a)jboss.org
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>> --
>>> Bela Ban
>>> Lead JGroups / Clustering Team
>>> JBoss - a division of Red Hat
>>>
>>
>> --
>> Manik Surtani
>> Lead, JBoss Cache
>> http://www.jbosscache.org
>> manik(a)jboss.org
>>
>>
>>
>>
>>
>
--
Brian Stansberry
Lead, AS Clustering
JBoss, a division of Red Hat
brian.stansberry(a)redhat.com
15 years, 8 months
CacheStores and expiration WAS: [horizon-commits] Horizon SVN: r40 - in trunk/src/test/java/org/horizon: expiry and 1 other directories.
by Manik Surtani
Ok, I have checked in all core changes around expiry, so that you can
now specify expiry:
(a) programmatically (per entry) or declaratively (cache-wide), and
(b) absolutely (lifespan), relatively (idle time), or both.
See examples, etc on:
http://www.jboss.org/community/docs/DOC-13449
So tests pass, and the core structure works well. The only thing is,
folks who have implemented CacheStores (Mircea and Adrian) may want to
revisit your implementations. Like I said tests pass, even the ones I
added to BaseCacheStoreTest to test all forms of expiration, but there
are probably optimisations you can do to prevent reading and
deserializing expired state, only to have isExpired() return true and
have to throw it away.
Cheers
Manik
Begin forwarded message:
> From: horizon-commits(a)lists.jboss.org
> Date: 25 March 2009 15:57:08 GMT
> To: horizon-commits(a)lists.jboss.org
> Subject: [horizon-commits] Horizon SVN: r40 - in trunk/src/test/java/
> org/horizon: expiry and 1 other directories.
> Reply-To: horizon-commits(a)lists.jboss.org
>
> Author: manik.surtani(a)jboss.com
> Date: 2009-03-25 11:57:08 -0400 (Wed, 25 Mar 2009)
> New Revision: 40
>
> Modified:
> trunk/src/test/java/org/horizon/container/
> SimpleDataContainerTest.java
> trunk/src/test/java/org/horizon/expiry/ExpiryTest.java
> trunk/src/test/java/org/horizon/expiry/ReplicatedExpiryTest.java
> trunk/src/test/java/org/horizon/loader/BaseCacheStoreTest.java
> Log:
> Expiry can now be set either as an absolute lifespan or a maxIdle time
>
> Modified: trunk/src/test/java/org/horizon/container/
> SimpleDataContainerTest.java
> ===================================================================
> --- trunk/src/test/java/org/horizon/container/
> SimpleDataContainerTest.java 2009-03-25 12:43:13 UTC (rev 39)
> +++ trunk/src/test/java/org/horizon/container/
> SimpleDataContainerTest.java 2009-03-25 15:57:08 UTC (rev 40)
> @@ -4,6 +4,7 @@
> import org.horizon.container.entries.InternalCacheEntry;
> import org.horizon.container.entries.TransientCacheEntry;
> import org.horizon.container.entries.MortalCacheEntry;
> +import org.horizon.container.entries.ImmortalCacheEntry;
>
> import java.util.HashSet;
> import java.util.Set;
> @@ -45,6 +46,40 @@
> assert dc.size() == 0;
> }
>
> + public void testUpdatingLastUsed() throws Exception {
> + long idle = 600000;
> + SimpleDataContainer dc = new SimpleDataContainer();
> + dc.put("k", "v", -1, -1);
> + InternalCacheEntry ice = dc.get("k");
> + assert ice instanceof ImmortalCacheEntry;
> + assert ice.getExpiryTime() == -1;
> + assert ice.getLastUsed() == -1;
> + assert ice.getCreated() == -1;
> + assert ice.getMaxIdle() == -1;
> + assert ice.getLifespan() == -1;
> + dc.put("k", "v", -1, idle);
> + long oldTime = System.currentTimeMillis();
> + Thread.sleep(10); // for time calc granularity
> + ice = dc.get("k");
> + assert ice instanceof TransientCacheEntry;
> + assert ice.getExpiryTime() == -1;
> + assert ice.getLastUsed() > oldTime;
> + Thread.sleep(10); // for time calc granularity
> + assert ice.getLastUsed() < System.currentTimeMillis();
> + assert ice.getMaxIdle() == idle;
> + assert ice.getCreated() == -1;
> + assert ice.getLifespan() == -1;
> +
> + oldTime = System.currentTimeMillis();
> + Thread.sleep(10); // for time calc granularity
> + assert dc.containsKey("k");
> +
> + // check that the last used stamp has been updated on a get
> + assert ice.getLastUsed() > oldTime;
> + Thread.sleep(10); // for time calc granularity
> + assert ice.getLastUsed() < System.currentTimeMillis();
> + }
> +
> public void testExpirableToImmortal() {
> SimpleDataContainer dc = new SimpleDataContainer();
> dc.put("k", "v", 6000000, -1);
>
> Modified: trunk/src/test/java/org/horizon/expiry/ExpiryTest.java
> ===================================================================
> --- trunk/src/test/java/org/horizon/expiry/ExpiryTest.java
> 2009-03-25 12:43:13 UTC (rev 39)
> +++ trunk/src/test/java/org/horizon/expiry/ExpiryTest.java
> 2009-03-25 15:57:08 UTC (rev 40)
> @@ -12,7 +12,7 @@
>
> import java.util.HashMap;
> import java.util.Map;
> -import java.util.concurrent.TimeUnit;
> +import static java.util.concurrent.TimeUnit.MILLISECONDS;
>
> @Test(groups = "functional", testName = "expiry.ExpiryTest")
> public class ExpiryTest {
> @@ -29,16 +29,17 @@
> TestingUtil.killCacheManagers(cm);
> }
>
> - public void testExpiryInPut() throws InterruptedException {
> + public void testLifespanExpiryInPut() throws
> InterruptedException {
> Cache cache = cm.getCache();
> long lifespan = 1000;
> - cache.put("k", "v", lifespan, TimeUnit.MILLISECONDS);
> + cache.put("k", "v", lifespan, MILLISECONDS);
>
> DataContainer dc = cache.getAdvancedCache().getDataContainer();
> InternalCacheEntry se = dc.get("k");
> assert se.getKey().equals("k");
> assert se.getValue().equals("v");
> assert se.getLifespan() == lifespan;
> + assert se.getMaxIdle() == -1;
> assert !se.isExpired();
> assert cache.get("k").equals("v");
> Thread.sleep(1100);
> @@ -46,14 +47,32 @@
> assert cache.get("k") == null;
> }
>
> - public void testExpiryInPutAll() throws InterruptedException {
> + public void testIdleExpiryInPut() throws InterruptedException {
> Cache cache = cm.getCache();
> + long idleTime = 1000;
> + cache.put("k", "v", -1, MILLISECONDS, idleTime, MILLISECONDS);
> +
> + DataContainer dc = cache.getAdvancedCache().getDataContainer();
> + InternalCacheEntry se = dc.get("k");
> + assert se.getKey().equals("k");
> + assert se.getValue().equals("v");
> + assert se.getLifespan() == -1;
> + assert se.getMaxIdle() == idleTime;
> + assert !se.isExpired();
> + assert cache.get("k").equals("v");
> + Thread.sleep(1100);
> + assert se.isExpired();
> + assert cache.get("k") == null;
> + }
> +
> + public void testLifespanExpiryInPutAll() throws
> InterruptedException {
> + Cache cache = cm.getCache();
> long startTime = System.currentTimeMillis();
> long lifespan = 1000;
> Map m = new HashMap();
> m.put("k1", "v");
> m.put("k2", "v");
> - cache.putAll(m, lifespan, TimeUnit.MILLISECONDS);
> + cache.putAll(m, lifespan, MILLISECONDS);
> while (System.currentTimeMillis() < startTime + lifespan) {
> assert cache.get("k1").equals("v");
> assert cache.get("k2").equals("v");
> @@ -68,11 +87,27 @@
> assert cache.get("k2") == null;
> }
>
> - public void testExpiryInPutIfAbsent() throws
> InterruptedException {
> + public void testIdleExpiryInPutAll() throws InterruptedException {
> Cache cache = cm.getCache();
> + long idleTime = 10000;
> + Map m = new HashMap();
> + m.put("k1", "v");
> + m.put("k2", "v");
> + cache.putAll(m, -1, MILLISECONDS, idleTime, MILLISECONDS);
> + assert cache.get("k1").equals("v");
> + assert cache.get("k2").equals("v");
> +
> + Thread.sleep(idleTime + 100);
> +
> + assert cache.get("k1") == null;
> + assert cache.get("k2") == null;
> + }
> +
> + public void testLifespanExpiryInPutIfAbsent() throws
> InterruptedException {
> + Cache cache = cm.getCache();
> long startTime = System.currentTimeMillis();
> long lifespan = 1000;
> - assert cache.putIfAbsent("k", "v", lifespan,
> TimeUnit.MILLISECONDS) == null;
> + assert cache.putIfAbsent("k", "v", lifespan, MILLISECONDS) ==
> null;
> while (System.currentTimeMillis() < startTime + lifespan) {
> assert cache.get("k").equals("v");
> Thread.sleep(50);
> @@ -86,19 +121,33 @@
> assert cache.get("k") == null;
>
> cache.put("k", "v");
> - assert cache.putIfAbsent("k", "v", lifespan,
> TimeUnit.MILLISECONDS) != null;
> + assert cache.putIfAbsent("k", "v", lifespan, MILLISECONDS) !=
> null;
> }
>
> - public void testExpiryInReplace() throws InterruptedException {
> + public void testIdleExpiryInPutIfAbsent() throws
> InterruptedException {
> Cache cache = cm.getCache();
> + long idleTime = 10000;
> + assert cache.putIfAbsent("k", "v", -1, MILLISECONDS,
> idleTime, MILLISECONDS) == null;
> + assert cache.get("k").equals("v");
> +
> + Thread.sleep(idleTime + 100);
> +
> + assert cache.get("k") == null;
> +
> + cache.put("k", "v");
> + assert cache.putIfAbsent("k", "v", -1, MILLISECONDS,
> idleTime, MILLISECONDS) != null;
> + }
> +
> + public void testLifespanExpiryInReplace() throws
> InterruptedException {
> + Cache cache = cm.getCache();
> long lifespan = 1000;
> assert cache.get("k") == null;
> - assert cache.replace("k", "v", lifespan,
> TimeUnit.MILLISECONDS) == null;
> + assert cache.replace("k", "v", lifespan, MILLISECONDS) == null;
> assert cache.get("k") == null;
> cache.put("k", "v-old");
> assert cache.get("k").equals("v-old");
> long startTime = System.currentTimeMillis();
> - assert cache.replace("k", "v", lifespan,
> TimeUnit.MILLISECONDS) != null;
> + assert cache.replace("k", "v", lifespan, MILLISECONDS) != null;
> assert cache.get("k").equals("v");
> while (System.currentTimeMillis() < startTime + lifespan) {
> assert cache.get("k").equals("v");
> @@ -115,7 +164,7 @@
>
> startTime = System.currentTimeMillis();
> cache.put("k", "v");
> - assert cache.replace("k", "v", "v2", lifespan,
> TimeUnit.MILLISECONDS);
> + assert cache.replace("k", "v", "v2", lifespan, MILLISECONDS);
> while (System.currentTimeMillis() < startTime + lifespan) {
> assert cache.get("k").equals("v2");
> Thread.sleep(50);
> @@ -128,4 +177,25 @@
> }
> assert cache.get("k") == null;
> }
> +
> + public void testIdleExpiryInReplace() throws
> InterruptedException {
> + Cache cache = cm.getCache();
> + long idleTime = 10000;
> + assert cache.get("k") == null;
> + assert cache.replace("k", "v", -1, MILLISECONDS, idleTime,
> MILLISECONDS) == null;
> + assert cache.get("k") == null;
> + cache.put("k", "v-old");
> + assert cache.get("k").equals("v-old");
> + assert cache.replace("k", "v", -1, MILLISECONDS, idleTime,
> MILLISECONDS) != null;
> + assert cache.get("k").equals("v");
> +
> + Thread.sleep(idleTime + 100);
> + assert cache.get("k") == null;
> +
> + cache.put("k", "v");
> + assert cache.replace("k", "v", "v2", -1, MILLISECONDS,
> idleTime, MILLISECONDS);
> +
> + Thread.sleep(idleTime + 100);
> + assert cache.get("k") == null;
> + }
> }
>
> Modified: trunk/src/test/java/org/horizon/expiry/
> ReplicatedExpiryTest.java
> ===================================================================
> --- trunk/src/test/java/org/horizon/expiry/ReplicatedExpiryTest.java
> 2009-03-25 12:43:13 UTC (rev 39)
> +++ trunk/src/test/java/org/horizon/expiry/ReplicatedExpiryTest.java
> 2009-03-25 15:57:08 UTC (rev 40)
> @@ -1,12 +1,16 @@
> package org.horizon.expiry;
>
> import org.horizon.Cache;
> +import org.horizon.container.entries.InternalCacheEntry;
> +import org.horizon.container.entries.TransientMortalCacheEntry;
> +import org.horizon.container.entries.MortalCacheEntry;
> +import org.horizon.container.entries.TransientCacheEntry;
> import org.horizon.config.Configuration;
> import org.horizon.test.MultipleCacheManagersTest;
> import org.testng.annotations.Test;
>
> import java.util.List;
> -import java.util.concurrent.TimeUnit;
> +import static java.util.concurrent.TimeUnit.MILLISECONDS;
>
> @Test(groups = "functional", testName = "expiry.ReplicatedExpiryTest")
> public class ReplicatedExpiryTest extends MultipleCacheManagersTest {
> @@ -20,18 +24,33 @@
> c2 = caches.get(1);
> }
>
> - public void testExpiryReplicates() throws InterruptedException {
> - long start = System.currentTimeMillis();
> + public void testLifespanExpiryReplicates() throws
> InterruptedException {
> long lifespan = 3000;
> - c1.put("k", "v", lifespan, TimeUnit.MILLISECONDS);
> + c1.put("k", "v", lifespan, MILLISECONDS);
> + InternalCacheEntry ice =
> c2.getAdvancedCache().getDataContainer().get("k");
>
> - while (System.currentTimeMillis() < start + lifespan) {
> - assert c1.get("k").equals("v");
> - assert c2.get("k").equals("v");
> - Thread.sleep(250);
> - }
> - Thread.sleep(1000);
> - assert c1.get("k") == null;
> - assert c2.get("k") == null;
> + assert ice instanceof MortalCacheEntry;
> + assert ice.getLifespan() == lifespan;
> + assert ice.getMaxIdle() == -1;
> }
> +
> + public void testIdleExpiryReplicates() throws
> InterruptedException {
> + long idle = 3000;
> + c1.put("k", "v", -1, MILLISECONDS, idle, MILLISECONDS);
> + InternalCacheEntry ice =
> c2.getAdvancedCache().getDataContainer().get("k");
> +
> + assert ice instanceof TransientCacheEntry;
> + assert ice.getMaxIdle() == idle;
> + assert ice.getLifespan() == -1;
> + }
> +
> + public void testBothExpiryReplicates() throws
> InterruptedException {
> + long lifespan = 10000;
> + long idle = 3000;
> + c1.put("k", "v", lifespan, MILLISECONDS, idle, MILLISECONDS);
> + InternalCacheEntry ice =
> c2.getAdvancedCache().getDataContainer().get("k");
> + assert ice instanceof TransientMortalCacheEntry;
> + assert ice.getLifespan() == lifespan;
> + assert ice.getMaxIdle() == idle;
> + }
> }
>
> Modified: trunk/src/test/java/org/horizon/loader/
> BaseCacheStoreTest.java
> ===================================================================
> --- trunk/src/test/java/org/horizon/loader/BaseCacheStoreTest.java
> 2009-03-25 12:43:13 UTC (rev 39)
> +++ trunk/src/test/java/org/horizon/loader/BaseCacheStoreTest.java
> 2009-03-25 15:57:08 UTC (rev 40)
> @@ -84,49 +84,101 @@
> return new ObjectStreamMarshaller();
> }
>
> -
> - public void testLoadAndStore() throws InterruptedException,
> CacheLoaderException {
> + public void testLoadAndStoreImmortal() throws
> InterruptedException, CacheLoaderException {
> assert !cs.containsKey("k");
> - InternalCacheEntry se = InternalEntryFactory.create("k", "v",
> -1, -1);
> + InternalCacheEntry se = InternalEntryFactory.create("k", "v");
> cs.store(se);
>
> assert cs.load("k").getValue().equals("v");
> assert cs.load("k").getLifespan() == -1;
> + assert cs.load("k").getMaxIdle() == -1;
> assert !cs.load("k").isExpired();
> assert cs.containsKey("k");
> + }
>
> - long now = System.currentTimeMillis();
> + public void testLoadAndStoreWithLifespan() throws
> InterruptedException, CacheLoaderException {
> + assert !cs.containsKey("k");
> +
> long lifespan = 120000;
> - se = InternalEntryFactory.create("k", "v", lifespan);
> + InternalCacheEntry se = InternalEntryFactory.create("k", "v",
> lifespan);
> cs.store(se);
>
> assert cs.load("k").getValue().equals("v");
> assert cs.load("k").getLifespan() == lifespan;
> + assert cs.load("k").getMaxIdle() == -1;
> assert !cs.load("k").isExpired();
> assert cs.containsKey("k");
>
> - now = System.currentTimeMillis();
> lifespan = 1;
> se = InternalEntryFactory.create("k", "v", lifespan);
> cs.store(se);
> - Thread.sleep(100);
> + Thread.sleep(10);
> assert se.isExpired();
> assert cs.load("k") == null;
> assert !cs.containsKey("k");
> }
>
> + public void testLoadAndStoreWithIdle() throws
> InterruptedException, CacheLoaderException {
> + assert !cs.containsKey("k");
> +
> + long idle = 120000;
> + InternalCacheEntry se = InternalEntryFactory.create("k", "v",
> -1, idle);
> + cs.store(se);
> +
> + assert cs.load("k").getValue().equals("v");
> + assert cs.load("k").getLifespan() == -1;
> + assert cs.load("k").getMaxIdle() == idle;
> + assert !cs.load("k").isExpired();
> + assert cs.containsKey("k");
> +
> + idle = 1;
> + se = InternalEntryFactory.create("k", "v", -1, idle);
> + cs.store(se);
> + Thread.sleep(10);
> + assert se.isExpired();
> + assert cs.load("k") == null;
> + assert !cs.containsKey("k");
> + }
> +
> + public void testLoadAndStoreWithLifespanAndIdle() throws
> InterruptedException, CacheLoaderException {
> + assert !cs.containsKey("k");
> +
> + long lifespan = 200000;
> + long idle = 120000;
> + InternalCacheEntry se = InternalEntryFactory.create("k", "v",
> lifespan, idle);
> + cs.store(se);
> +
> + assert cs.load("k").getValue().equals("v");
> + assert cs.load("k").getLifespan() == lifespan;
> + assert cs.load("k").getMaxIdle() == idle;
> + assert !cs.load("k").isExpired();
> + assert cs.containsKey("k");
> +
> + idle = 1;
> + se = InternalEntryFactory.create("k", "v", lifespan, idle);
> + cs.store(se);
> + Thread.sleep(10);
> + assert se.isExpired();
> + assert cs.load("k") == null;
> + assert !cs.containsKey("k");
> + }
> +
> public void testStopStartDoesntNukeValues() throws
> InterruptedException, CacheLoaderException {
> assert !cs.containsKey("k1");
> assert !cs.containsKey("k2");
>
> - long now = System.currentTimeMillis();
> long lifespan = 1;
> + long idle = 1;
> InternalCacheEntry se1 = InternalEntryFactory.create("k1",
> "v1", lifespan);
> InternalCacheEntry se2 = InternalEntryFactory.create("k2",
> "v2");
> + InternalCacheEntry se3 = InternalEntryFactory.create("k3",
> "v3", -1, idle);
> + InternalCacheEntry se4 = InternalEntryFactory.create("k4",
> "v4", lifespan, idle);
>
> cs.store(se1);
> cs.store(se2);
> - Thread.sleep(100);
> + cs.store(se3);
> + cs.store(se4);
> + Thread.sleep(10);
> cs.stop();
> cs.start();
> assert se1.isExpired();
> @@ -135,7 +187,12 @@
> assert cs.load("k2") != null;
> assert cs.containsKey("k2");
> assert cs.load("k2").getValue().equals("v2");
> -
> + assert se3.isExpired();
> + assert cs.load("k3") == null;
> + assert !cs.containsKey("k3");
> + assert se3.isExpired();
> + assert cs.load("k3") == null;
> + assert !cs.containsKey("k3");
> }
>
>
> @@ -246,11 +303,11 @@
>
> public void
> testRollbackFromADifferentThreadReusingTransactionKey() throws
> CacheLoaderException, InterruptedException {
>
> - cs.store(InternalEntryFactory.create("old", "old", -1, -1));
> + cs.store(InternalEntryFactory.create("old", "old"));
>
> List<Modification> mods = new ArrayList<Modification>();
> - mods.add(new Store(InternalEntryFactory.create("k1", "v1",
> -1, -1)));
> - mods.add(new Store(InternalEntryFactory.create("k2", "v2",
> -1, -1)));
> + mods.add(new Store(InternalEntryFactory.create("k1", "v1")));
> + mods.add(new Store(InternalEntryFactory.create("k2", "v2")));
> mods.add(new Remove("k1"));
> mods.add(new Remove("old"));
> final Transaction tx =
> EasyMock.createNiceMock(Transaction.class);
> @@ -350,13 +407,14 @@
>
> public void testPurgeExpired() throws Exception {
> long lifespan = 1000;
> + long idle = 500;
> cs.store(InternalEntryFactory.create("k1", "v1", lifespan));
> - cs.store(InternalEntryFactory.create("k2", "v2", lifespan));
> - cs.store(InternalEntryFactory.create("k3", "v3", lifespan));
> + cs.store(InternalEntryFactory.create("k2", "v2", -1, idle));
> + cs.store(InternalEntryFactory.create("k3", "v3", lifespan,
> idle));
> assert cs.containsKey("k1");
> assert cs.containsKey("k2");
> assert cs.containsKey("k3");
> - Thread.sleep(lifespan + 100);
> + Thread.sleep(lifespan + 10);
> cs.purgeExpired();
> assert !cs.containsKey("k1");
> assert !cs.containsKey("k2");
>
> _______________________________________________
> horizon-commits mailing list
> horizon-commits(a)lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/horizon-commits
--
Manik Surtani
Lead, JBoss Cache
http://www.jbosscache.org
manik(a)jboss.org
15 years, 8 months
Re: lock() and unlock() methods ?
by Manik Surtani
I can see some use when using a distributed cache as a distributed
file system (JCR, etc)...
On 20 Mar 2009, at 09:14, Bela Ban wrote:
> Let's hear from others before we put anything on the roadmap.
>
> I recall Brian mentioning his need for locks, but AFAIR not in
> conjunction with JBossCache but with Farming...
>
>
> Manik Surtani wrote:
>>
>> On 20 Mar 2009, at 08:36, Bela Ban wrote:
>>
>>> I know, but what he wants to do is
>>> #1 Read a value
>>> #2 Based on that value (which I assume shouldn't change from
>>> underneath him), do some computations
>>> #3 Write the changed value back
>>>
>>> I guess the problem is that some other TX could change the value
>>> and have the later TX fail & roll back...
>>>
>>> AFAIR we don't have Cache.lock(K) and unlock(K), do we ? If so,
>>> would it make sense to add them ? And then we'd have to think about
>>
>> We don't at the moment. Adding them is simple, making them scale/
>> perform well is hard. :-)
>>
>> It would be a simple LockCommand which is broadcast (anycast?) via
>> RPC. If it doesn't return (in time), assume we don't have the lock
>> and throw a timeout exception. This call would *have* to be
>> synchronous though, it can't work in an async manner.
>>
>>> * how this fares with TX-incurred locking
>>
>> It would hold the locks until unlock() is called, or a tx
>> completes, whichever happens first, I guess.
>>
>>>
>>> * what type of locks lock() acquires
>>
>> Write locks. We don't have such a thing as read locks in Horizon
>> or even JBC3's MVCC.
>>
>>> WDYT ?
>>
>> I don't mind putting it on the Horizon roadmap, but I can't promise
>> when it would get done - its just a case of prioritising stuff. If
>> another resource is looking unlikely/delayed we have a lot of stuff
>> on our plate... :-(
>>
>>>
>>>
>>>
>>> Manik Surtani wrote:
>>>> No, a tx +RR is still optimistic cluster-wide in that it is only
>>>> on tx commit (tx prepare, actually) that remote locks are acquired.
>>>>
>>>> This essentially is a distributed lock.
>>>>
>>>>
>>>> On 20 Mar 2009, at 07:34, Bela Ban wrote:
>>>>
>>>>> Do we have a hard-lock mechanism like the one below for
>>>>> Coherence ?
>>>>>
>>>>> Would a TX with RR be the equivalent ?
>>>>>
>>>>>
>>>>> -------- Original Message --------
>>>>> Subject: RE: [javagroups-users] Distributed Lock Manager
>>>>> Listener
>>>>> Date: Thu, 19 Mar 2009 12:03:42 -0500
>>>>> From: Urciolo, Kevin J (IS) <Kevin.Urciolo(a)ngc.com>
>>>>> To: Bela Ban <belaban(a)yahoo.com>
>>>>> CC: <javagroups-users(a)lists.sourceforge.net>
>>>>> References: <0E36CF63779A934D876C5E7FD29E74EB01FA4FFC(a)XMBIL123.northgrum.com
>>>>> > <49C206DC.8030608(a)yahoo.com>
>>>>>
>>>>>
>>>>>
>>>>> I am trying to accomplish the locking mechanism as shown in this
>>>>> example
>>>>> from Coherence. I need to execute a piece of code that is
>>>>> mutually
>>>>> exclusive throughout the group.
>>>>>
>>>>> I looked at the VotingAdapter. I seemed to get the
>>>>> notifications before
>>>>> the lock was released, but caused the thread waiting for the
>>>>> lock to try
>>>>> again too early and get another LockNotGrantedException.
>>>>>
>>>>> NamedCache cache = CacheFactory.getCache("dist-cache");
>>>>> Object key = "example_key";
>>>>> cache.lock(key, -1);
>>>>> try
>>>>> {
>>>>> Object value = cache.get(key);
>>>>> // application logic
>>>>> cache.put(key, value);
>>>>> }
>>>>> finally
>>>>> {
>>>>> // Always unlock in a "finally" block
>>>>> // to ensure that uncaught exceptions
>>>>> // don't leave data locked
>>>>> cache.unlock(key);
>>>>> }
>>>>> -----Original Message-----
>>>>> From: Bela Ban [mailto:belaban@yahoo.com] Sent: Thursday, March
>>>>> 19, 2009 4:48 AM
>>>>> To: Urciolo, Kevin J (IS)
>>>>> Cc: javagroups-users(a)lists.sourceforge.net
>>>>> Subject: Re: [javagroups-users] Distributed Lock Manager Listener
>>>>>
>>>>>
>>>>>
>>>>> Urciolo, Kevin J (IS) wrote:
>>>>>> I would like to use the distributed lock manager. However, I
>>>>>> would like my components to block until a lock is available
>>>>>> instead of getting an exception thrown.
>>>>>
>>>>> What if the lock cannot be granted ? There's a
>>>>> LockNotGrantedException
>>>>> when this happens. I also assume you would not want to wait
>>>>> forever if a
>>>>> lock is held by a different owner.
>>>>>
>>>>>> Is this possible? If not, is it possible to listen for events
>>>>>> on locks
>>>>>
>>>>>> so I can implement my own listener mechanism?
>>>>>
>>>>> There's a VotingAdapter class which implements
>>>>> VoteResponseProcessor. This class has callbacks, but of course
>>>>> you could also write your own
>>>>> implementation
>>>>>
>>>>> --
>>>>> Bela Ban
>>>>> Lead JGroups / Clustering Team
>>>>> JBoss - a division of Red Hat
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Bela Ban
>>>>> Lead JGroups / Clustering Team
>>>>> JBoss - a division of Red Hat
>>>>>
>>>>>
>>>>
>>>> --
>>>> Manik Surtani
>>>> Lead, JBoss Cache
>>>> http://www.jbosscache.org
>>>> manik(a)jboss.org
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>> --
>>> Bela Ban
>>> Lead JGroups / Clustering Team
>>> JBoss - a division of Red Hat
>>>
>>
>> --
>> Manik Surtani
>> Lead, JBoss Cache
>> http://www.jbosscache.org
>> manik(a)jboss.org
>>
>>
>>
>>
>>
>
> --
> Bela Ban
> Lead JGroups / Clustering Team
> JBoss - a division of Red Hat
--
Manik Surtani
Lead, JBoss Cache
http://www.jbosscache.org
manik(a)jboss.org
15 years, 8 months
ReflectionUtil.getAnnotation() vs @Inherited for veriying superclasses
by Galder Zamarreno
Hi,
If we make cache listener or scope annotations @Inherited, we'd avoid
having to check superclasses in ReflectionUtil.getAnnotation(). Is there
any particular reason why our annotations are not @Inherited and we
check superclasses ourselves instead?
We still need to check implemented interfaces manually.
Cheers,
--
Galder Zamarreño
Sr. Software Maintenance Engineer
JBoss, a division of Red Hat
15 years, 8 months
Re: JGroups and concurrent FLUSHes
by Bela Ban
It would be mainly used to prevent A from releasing a lock owned by B.
Create a simple lock yourself, inside of FLUSH
Vladimir Blagojevic wrote:
> On 3/8/09 9:59 AM, Bela Ban wrote:
>> I think we should turn flushInProgress into something akin to a lock,
>> which additionally records its locker. So if you have a
>> lock.tryAcquire(Object caller) which fails immediately if the lock is
>> already locked by someone != caller.
>>
>> A lock.release(Object caller) fails if lock.owner != caller.
> This is to prevent multiple threads in one stack invoking startFlush?
> Which lock class do you recommend?
>
--
Bela Ban
Lead JGroups / JBoss Clustering team
JBoss - a division of Red Hat
15 years, 8 months
Re: [jbosscache-dev] Cache benchmark for jbosscache-1.4.1 is broken
by Galder Zamarreno
I don't have admin rights but could someone that has them create a new
Component within JBCACHE for the benchmark framework? Don't think we
need a brand new project in JIRA for it, a new component in JBCACHE
should be enough.
Mircea Markus wrote:
> Hi Galder,
>
> Thanks for spotting this out.
> We don't currently have an JIRA project for it, but you can add subtasks
> to https://jira.jboss.org/jira/browse/JBCACHE-1335.
>
> Cheers,
> Mircea
>
> Galder Zamarreno wrote:
>> Dude,
>>
>> Eventually figured out why no matter how I did it, the benchmark for
>> JBC 1.4.x did not work:
>>
>> org.cachebench.cachewrappers.JBossCacheWrapper inside jbosscache-1.4.1
>> shows:
>>
>> public Object getReplicatedData(List<String> l, String key)
>> {
>> return null;
>> }
>>
>> So, replication works but checking whether the data has been
>> replicated has not been implemented!! I'll get it fixed.
>>
>> Where do we fill JIRAs for the cache benchmark framework?
>>
>> Cheers,
>
--
Galder Zamarreño
Sr. Software Maintenance Engineer
JBoss, a division of Red Hat
15 years, 8 months
Cache bean deployment via MC failing when TRACE enabled on org.jboss.kernel
by Galder Zamarreno
Hi,
Bear with me on this one, it's a bit long :)
I've been running some tests creating Cache instances via MC and I've
noticed that when TRACE logging is enabled on org.jboss.kernel, my Cache
beans are not deployed whereas when org.jboss.kernel is set to DEBUG or
higher, Cache beans deploy fine.
The error I'm getting is the following:
2009-03-03 21:40:51,505 ERROR [AbstractKernelController] (main) Error
installing to Instantiated: name=CacheClusterA1 state=Described
java.lang.UnsupportedOperationException: Not supported in UnversionedNode
at org.jboss.cache.AbstractNode.getChildrenDirect(AbstractNode.java:277)
at
org.jboss.cache.mvcc.NodeReference.getChildrenDirect(NodeReference.java:272)
at
org.jboss.cache.invocation.NodeInvocationDelegate.getChildrenDirect(NodeInvocationDelegate.java:163)
at org.jboss.cache.DataContainerImpl.numNodes(DataContainerImpl.java:461)
at
org.jboss.cache.DataContainerImpl.getNumberOfNodes(DataContainerImpl.java:438)
at org.jboss.cache.DataContainerImpl.toString(DataContainerImpl.java:394)
at org.jboss.cache.DataContainerImpl.toString(DataContainerImpl.java:372)
at
org.jboss.cache.invocation.CacheInvocationDelegate.toString(CacheInvocationDelegate.java:144)
at java.lang.String.valueOf(String.java:2615)
at org.jboss.util.JBossStringBuilder.append(JBossStringBuilder.java:114)
at
org.jboss.dependency.plugins.AbstractControllerContext.toString(AbstractControllerContext.java:362)
Looks like in TRACE mode, MC is trying to print the Cache when this is
not fully started.
To try to understand this, let's look at what DataContainerImpl logs
when org.jboss.kernel is set to DEBUG:
log4j-jboss-kerneldebug.log:2894:2009-03-03 21:40:24,249 2198 TRACE
[org.jboss.cache.DataContainerImpl] (main:) Starting data container.
Using MVCC? false
log4j-jboss-kerneldebug.log:2895:2009-03-03 21:40:24,274 2223 TRACE
[org.jboss.cache.DataContainerImpl] (main:) Setting root node to an
instance of class org.jboss.cache.mvcc.NodeReference
...
log4j-jboss-kerneldebug.log:3038:2009-03-03 21:40:24,336 2285 TRACE
[org.jboss.cache.DataContainerImpl] (main:) Starting data container.
Using MVCC? true
log4j-jboss-kerneldebug.log:3039:2009-03-03 21:40:24,338 2287 DEBUG
[org.jboss.cache.DataContainerImpl] (main:) Setting rootInternal to
NodeReference{delegate=UnversionedNode[ /]}
After MVCC has been set to true, DataContainerImpl.getNumberOfNodes() is
able to get the number of nodes successfully:
if (!usingMvcc) return numNodes(root) - 1;
return numNodesMvcc(rootInternal) - 1;
However, if in between the two "Starting data container" messages,
someone (i.e. MC), tries to get the number of nodes (via toString), then
Cache tries to get number of nodes of a MVCC node as a non MVCC node
failing with the exception above. This is exactly what happens when you
enable TRACE on MC kernel.
numNodesMvcc() calls getChildren(). numNodes calls getChildrenDirect().
With this TRACE enabled, log only show the first two lines:
log4j-jboss-kerneltrace.log:6731:2009-03-03 21:40:51,468 2817 TRACE
[org.jboss.cache.DataContainerImpl] (main:) Starting data container.
Using MVCC? false
log4j-jboss-kerneltrace.log:6732:2009-03-03 21:40:51,475 2824 TRACE
[org.jboss.cache.DataContainerImpl] (main:) Setting root node to an
instance of class org.jboss.cache.mvcc.NodeReference
So, how do we solve this?
I'm not sure I understand why DataContainerImpl.createRootNode() is
called twice. The very first call, which seems to come from
DataContainerImpl.injectDependencies() method (annotated with @Inject)
looks suspicious. Why does it look suspicious? Because calls like this
expect a config to be set. And when they're called initially from
@Inject, the config object is not still set (when the call comes as part
of the start operation, config is indeed set)
usingMvcc = config != null && config.getNodeLockingScheme() ==
NodeLockingScheme.MVCC;
And this returning false, when in fact the config is set to MVCC is what
results of number of nodes being calculated incorrectly.
Not sure on how to fix this though.
Thoughts?
--
Galder Zamarreño
Sr. Software Maintenance Engineer
JBoss, a division of Red Hat
15 years, 8 months
Cache benchmark for jbosscache-1.4.1 is broken
by Galder Zamarreno
Dude,
Eventually figured out why no matter how I did it, the benchmark for JBC
1.4.x did not work:
org.cachebench.cachewrappers.JBossCacheWrapper inside jbosscache-1.4.1
shows:
public Object getReplicatedData(List<String> l, String key)
{
return null;
}
So, replication works but checking whether the data has been replicated
has not been implemented!! I'll get it fixed.
Where do we fill JIRAs for the cache benchmark framework?
Cheers,
--
Galder Zamarreño
Sr. Software Maintenance Engineer
JBoss, a division of Red Hat
15 years, 8 months