Welcome to the list, Sanne.
The Node API already has atomic methods like putIfAbsent(), replace(),
etc., but these don't deal with nodes becoming invalid. Using return
types to deal with invalid cases won't work since we need those return
types for other purposes, such as Node.get(...) which would return an
attribute value.
The cases where a node becomes invalid are:
1. Another thread removes the node.
In this case, an exception should be thrown, since the reference to
Node that the calling code has is now meaningless and the node should
be fetched again by performing a cache.getNode().
2. The thread gets evicted.
In this case, the node *could* be reloaded from a cache loader, and
the correct solution here would be to transparently reload the node
for the user. Of course, if no cache loader is used, an eviction
event is the same as a removal event, as in 1. So, after attempting
to reload the node, if the node is still invalid, revert to behaviour
as in 1.
- Manik
On 16 May 2008, at 10:55, Sanne Grinovero wrote:
Hi All,
I have been reading some time but please consider my opinion as a
complete newbie.
Still I have some experience with concurrency and would like to
highlight your attention
on the patterns used in the JDK util.concurrency; I use them often and
they provide a very clean approach
for this sort of problem:
the AtomicBoolean (for example) has
boolean compareAndSet( boolean expectedValue, boolean newValue)
the ConcurrentHashMap has
boolean putIfAbsent(Object key, Object value)
they all return false if the condition required to set the new value
is no longer valid,
so I think a clean approach would be to define the Node manipulation
API
as "boolen setIfValid( ... ) and return false when the Node is no
longer valid,
so a retry code could be written in clean and readable code.
This way you avoid node locking, and also you have fail-fast: if I had
to mark a node
as "do not evict" it means I'm doing some useless work, as far as I
have understood
it the result will be thrown to garbage as soon as we finished working
on the Node,
I think it would be preferrable to avoid the work at all or write it
to the most current Node.
(please just let me know if I wrote stupid things, as I said I still
don't know
the internal wroking of the cache)
regards,
Sanne Grinovero
2008/5/16 Elias Ross <genman(a)noderunner.net>:
> On Thu, May 15, 2008 at 3:52 PM, Manik Surtani <manik(a)jboss.org>
> wrote:
>
>> So the question is this - with potentially likely events marking a
>> node as
>> invalid - especially with eviction - should we throw a
>> NodeNotValidException? Since (as of 2.1.0), the Node
>> implementation that a
>> user has is an instance of NodeInvocationDelegate which in turn
>> has a
>> reference to an UnversionedNode, perhaps we should handle the NNVE
>> within
>> the NodeInvocationDelegate and perform a lookup internally and
>> refresh the
>> UnversionedNode reference, and THEN throw a NNVE if we can't fetch
>> the node?
>
> Something feels wrong about using exceptions as message passing
> events
> and flow control.
>
> You should be able to check if a node is invalid before that
> exception
> gets thrown. And if you do a retry, it seems possible to get stuck in
> a loop: Exception, refresh succeeds, but immediate eviction again,
> then exception again, etc. Maybe it's really unlikely, but it'd be a
> bummer.
>
> Wouldn't an evict require a write lock? If so, then this couldn't
> happen.
>
> Or do this as part of the interception:
> 1. Pre-fetch node, mark as "do not evict", then check again if node
> is
> valid (would have to use a volatile flag I think)
> 2. Do your business
> 3. Unmark
> _______________________________________________
> jbosscache-dev mailing list
> jbosscache-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/jbosscache-dev
>
--
Manik Surtani
Lead, JBoss Cache
manik(a)jboss.org