----- Original Message -----
From: "Galder Zamarreño" <galder(a)redhat.com>
To: "infinispan -Dev List" <infinispan-dev(a)lists.jboss.org>, "Paul
Ferraro" <paul.ferraro(a)redhat.com>
Sent: Monday, September 1, 2014 11:08:45 AM
Subject: Asynchronous cache's "void put()" call expectations changed from
6.0.0 to 6.0.1/7.0
Hi all,
@Paul, this might be important for WF if using async repl caches (the same I
think applies to distributed async caches too)
Luckily, Dan warned me that of this behavioral change well in advance.
Any time we need a reliable return value from a Cache.put(...), we use
Flag.FORCE_SYNCHRONOUS so that the same code will work for sync and async caches alike.
Today I’ve been trying to upgrade Infinispan version in Hibernate
master from
6.0.0.Final to 7.0.0.Beta1. Overall, it’s all worked fine but there’s one
test that has started failing.
Essentialy, this is a clustered test for a repl async cache (w/ cluster cache
loader) where a non-owner cache node does put() and immediately, on the same
cache, it calls a get(). The test is failing because the get() does not see
the effects of the put(), even if both operations are called on the same
cache instance.
According to Dan, this should have been happening since [1] was implemented,
but it’s really started happening since [2] when lock delegation was enabled
for replicated caches (EntryWrappingInterceptor.isUsingLockDelegation is now
true whereas in 6.0.0 it was false).
Not sure we set expectations in this regard, but clearly it’s big change in
terms of expectations on when “void put()” completes for async repl caches.
I’m not sure how we should handle this, but it definitely needs some
discussion and adjuts documentation/javadoc if needed. Can we do something
differently?
Indepent of how we resolve this, this is the result of once again of trying
to shoehole async behaviour into sync APIs. Any async caches (DIST, INV,
REPL) should really be accessed exclusively via the AsyncCache API, where
you can return quickly and use the future, and any listener to attach to it
(a bit ala Java8’s CompletableFuture.map lambda calls) as a way to signal
that the operation has completed, and then you have an API and cache mode
that make sense and is consistent with how async APIs work.
Right now, when a repl async cache’s “void put()” call is not very well
defined. Does it return when message has been put on the network? What
impact does it have in the local cache contents?
Also, a very big problem of the change of behaviour is that if left like
that, you are forcing users to code differently, using the same “void put()”
API depending on the configuration (whether async/sync). As clearly shown by
the issue above, this is very confusing. It’s a lot more logical IMO, and
I’ve already sent an email on this very same topic [3] back in January, that
whether a cache is sync or async should be based purely on the API used and
forget about the static configuration flag on whether the cache is async or
sync.
I would agree would this last statement. Consistent semantics are a good thing.
If you do change this, however, just let me know well in advance.