[
https://issues.jboss.org/browse/ISPN-2956?page=com.atlassian.jira.plugin....
]
Galder Zamarreño commented on ISPN-2956:
----------------------------------------
I've been looking into this last week trying to come up with a solution that would
make these kind of operations reliable. For that, a change of protocol is required and as
we near the completion of Hot Rod 2.0 version, it's probably a good time to address
this.
To support these kind of use cases, Hot Rod needs to move from the server producing the
entry's version, to having the Hot Rod clients produce the version information and
shipping it along with each modification. If the operation fails and the client receives
the failure, it would be able to retry the operation. The retry would essentially involve
sending the same operation, with a new message ID and a new RETRY flag. When the server
receives a retry operation, it would check whether the entry is already present in the
cache (cluster-wide), and check if the version provided by the client is the same as the
entry in memory. If it's not, in the case of putIfAbsent, it would mean that entry has
been overriden by someone else since the retry, and putIfAbsent would just return false.
It would be the responsibility of the Hot Rod client implementations to generate the
version and hence it would be transparent for the Hot Rod users.
All operations making modifications, except clear, would ship the version to be applied
with the entry, and operations such as replaceIfUnmodified would ship both, the version to
compare the entry with, and the version to be used if the replace succeeds. Even
operations such as put() would need to ship to the server the version because if the
clients provide the flag to force to return the previous value, they need to provide
atomicity guarantees.
putIfAbsent on Hot Rod Java client doesn't reliably fulfil
contract
-------------------------------------------------------------------
Key: ISPN-2956
URL:
https://issues.jboss.org/browse/ISPN-2956
Project: Infinispan
Issue Type: Bug
Components: Remote Protocols
Reporter: Galder Zamarreño
Assignee: Galder Zamarreño
Priority: Minor
Labels: hotrod-java-client, remote-clients
Fix For: 7.0.0.Beta1
Hot Rod's putIfAbsent might have issues on some edge cases:
{quote}I want to know whether the putting entry already exists in the remote
cache cluster, or not.
I thought that RemoteCache.putIfAbsent() would be useful for that
purpose, i.e.,
{code}
if (remoteCache.putIfAbsent(k,v) == null) {
// new entry.
} else {
// k already exists.
}
{code}
But no.
The putIfAbsent() for new entry may return non-null value, if one of the
server crushed while putting.
The behavior is like the following:
1. Client do putIfAbsent(k,v).
2. The server receives the request and sends replication requests to
other servers. If the server crushed before completing replication, some
servers own that (k,v), but others not.
3. Client receives the error. The putIfAbsent() internally retries the
same request to the next server in the cluster server list.
4. If the next server owns the (k,v), the putIfAbsent() returns the
replicated (k,v) at the step 2, without any error.
So, putIfAbsent() is not reliable for knowing whether the putting entry
is *exactly* new or not.
Does anyone have any idea/workaround for this purpose?{quote}
A workaround is to do this:
{quote}We got a simple solution, which can be applied to our customer's application.
If each value part of putting (k,v) is unique or contains unique value,
the client can do *double check* wether the entry is new.
{code}
val = System.nanoTime(); // or uuid is also useful.
if ((ret = cache.putIfAbsent(key, val)) == null
|| ret.equals(val)) {
// new entry, if the return value is just the same.
} else {
// key already exists.
}
{code}
We are proposing this workaround which almost works fine.{quote}
However, this is a bit of a cludge.
Hot Rod should be improved with an operation that allows a version to be passed when
entry is created, instead of relying on the client generating it.
--
This message was sent by Atlassian JIRA
(v6.2.3#6260)