--
Galder Zamarreño
Infinispan, Red Hat
On 6 Apr 2017, at 11:04, Radim Vansa <rvansa(a)redhat.com>
wrote:
On 04/06/2017 12:15 AM, Katia Aresti wrote:
>
>
> On Wed, Apr 5, 2017 at 9:56 AM, Radim Vansa <rvansa(a)redhat.com
> <mailto:rvansa@redhat.com>> wrote:
>
> On 04/04/2017 06:40 PM, William Burns wrote:
>>
>>
>> On Tue, Apr 4, 2017 at 11:45 AM Katia Aresti <karesti(a)redhat.com
> <mailto:karesti@redhat.com>
>> <mailto:karesti@redhat.com <mailto:karesti@redhat.com>>> wrote:
>>
>> Hi all,
>>
>> As you probably know, Will and I are working on the vert-x
>> infinispan integration [1], where the primary goal is to make
>> infinispan the default cluster management of vert-x. (yeah!)
>> Vert-x needs support for an Async Multimap. Today's
> implementation
>> is a wrapper on a normal Cache where only Cache Key's are
> used to
>> implement the multi map [2].
>> This is not very efficient, so after trying some other
> alternative
>> implementations [3] that don't fully work (injection not
> working),
>> Will and I have come to the conclusion that it might be a good
>> idea to start having our own native CacheMultimap. This first
>> multimap won't support duplicate values on key's.
>>
>> As a quick start, the smallest multimap we need should implement
>> the following interface :
>>
>> I agree that having a very slim API to start should be better
> since we
>> know how much trouble we get into implementing a very large API like
>> ConcurrentMap :)
>>
>> public interface CacheMultimap<K,V> {
>>
>
> I don't see anything async in this interface. If that's async, provide
> CompletableFuture return values.
> I am also considering if we want any fire & forget variants for these
> operations, but since we have to do retries to achieve consistency
> (and
> therefore we need some messages from owners to originator), I wouldn't
> include them.
>
>
> Today's vert-x API calls the vertx.executeBlocking(future => cache...)
>
> I considered the option of CompletableFuture, but for simplicity I
> suggested the basic method.
> Today's CacheAPI makes a difference between "put" and
"putAsync".
> Would you call the interface CacheMultimapAsync or CacheMultimap with
> addAsyc method ?
"In a perfect world, there will be no war or hunger, all APIs will be
written asynchronously and bunny rabbits will skip hand-in-hand with
baby lambs across sunny green meadows." (quoting Vert.x docs)
While minimalistic API is a good way to start, it shouldn't contain
anything we'd want to get rid of in close future. And especially since
the main drive for multimaps is Vert.x which consumes asynchronous APIs
(and has support for legacy synchronous APIs, the executeBlocking
method), we should have the design adapted to that from the beginning.
Amen!
CompletableFuture is not a rocket science, and you can use the
already
asynchronous Infinispan internals.
Indeed!
CompletableFuture is good.
In hindsight, I would have maybe chosen java.util.concurrent.CompletionStage since
it's more flexible (interface vs class), and doesn't bring in
java.util.concurrent.Future which contains blocking methods.
CompletableFuture/CompletionStage works for single returns. The bigger problem is when you
want multiple returns asynchronously. Here a can of worms opens up, e.g. do you push the
results? do you pull the results?
For the functional map API, we experimented with a pull model using Traversable. A push
model is harder to implement and non-trivial, and there you're getting into Rx
territory.
I don't think we should have two interfaces, I believe that
single
interface with async methods only is absolutely sufficient.
^ I'm not so sure actually... Both sets of methods are used for different use cases.
Conceptually and from a user's perspective, I'd rather have separate interfaces
since I'd not expect calls to both use cases to be interleaved.
Though I
wouldn't add the *Async suffix at all there. If someone wants to execute
the methods synchronously he can call .get() or .join() - just 6/7
characters more.
^ We shouldn't promote calling Future.get() for asynchronous APIs since it goes
against everything that async APIs stand for ;)
>
>> V put(K key,V value);
>>
>> This should probably return a boolean or Void. I am leaning towards
>> the first, but I am open either way.
>
> I would rather call this "add", as vert-x does. CompletableFuture as
> return type here will allow to easily register the handler
>
>
> -1 I prefer keeping "put" name because it is still a Map and makes
> more sense to me considering the actual Cache API too. The return type
> V was a transcription mistake, it should be void for me, as Will
> pointed out.
To me "put" is linked with overwriting the previous value, while you add
to the underlying collection or create a new single-element one. But
whatever, I care more about the return values :)
R.
>
>
>> Collection<V> get(K key);
>>
>> boolean remove(K key,V value);
>>
>> We probably want a `boolean remove(K key)` method as well that
> removes
>> all values mapped to the given key.
>
> What about "reset(key)"?
>
>
>> }
>>
>> CacheMultimapImpl will be a wrapper on a normal Cache,
> similar to [3].
>>
>> We could add a new method in EmbeddedCacheManager.java
>>
>> <K, V> CacheMultimap<K, V> getCacheMultimap(String cacheName,
>> boolean createIfAbsent);
>>
>>
>> I was thinking maybe this would exist in a separate module
> (outside of
>> core)? or class that wraps (similar to DistributedExecutor) instead.
>> My worry is about transactions, since the entry point to that is
>> through Cache interface. The other option is we could add a
> `getCache`
>> method on the `CacheMultiMap`.
>
> +1 Since the names of multimaps and maps will clash, we shouldn't hide
> that the underlying implementation is a Cache, so I'd suggest
> something like
>
> static <K, V> CacheMultimap<K, V> CacheMultimapFactory.get(Cache<K,
> Object> c) { ... }
>
>>
>>
>> Implementation will create a cache as always and return a new
>> CacheMultimapImpl(cache).
>>
>> What do you think ? Please fell free to suggest any other
>> alternative or idea.
>>
>> Cheers
>>
>> Katia
>>
>> [1]
https://github.com/vert-x3/vertx-infinispan
> <
https://github.com/vert-x3/vertx-infinispan>
>>
>> [2]
>>
>
https://github.com/vert-x3/vertx-infinispan/blob/master/src/main/java/io/...
>
<
https://github.com/vert-x3/vertx-infinispan/blob/master/src/main/java/io/...
>>
>> [3]
>
https://gist.github.com/karesti/194bb998856d4a2828d83754130ed79c
> <
https://gist.github.com/karesti/194bb998856d4a2828d83754130ed79c>
>> _______________________________________________
>> infinispan-dev mailing list
>> infinispan-dev(a)lists.jboss.org
> <mailto:infinispan-dev@lists.jboss.org>
> <mailto:infinispan-dev@lists.jboss.org
> <mailto:infinispan-dev@lists.jboss.org>>
>>
https://lists.jboss.org/mailman/listinfo/infinispan-dev
> <
https://lists.jboss.org/mailman/listinfo/infinispan-dev>
>>
>>
>>
>> _______________________________________________
>> infinispan-dev mailing list
>> infinispan-dev(a)lists.jboss.org
> <mailto:infinispan-dev@lists.jboss.org>
>>
https://lists.jboss.org/mailman/listinfo/infinispan-dev
> <
https://lists.jboss.org/mailman/listinfo/infinispan-dev>
>
>
> --
> Radim Vansa <rvansa(a)redhat.com <mailto:rvansa@redhat.com>>
> JBoss Performance Team
>
> _______________________________________________
> infinispan-dev mailing list
> infinispan-dev(a)lists.jboss.org <mailto:infinispan-dev@lists.jboss.org>
>
https://lists.jboss.org/mailman/listinfo/infinispan-dev
> <
https://lists.jboss.org/mailman/listinfo/infinispan-dev>
>
>
>
>
> _______________________________________________
> infinispan-dev mailing list
> infinispan-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/infinispan-dev
--
Radim Vansa <rvansa(a)redhat.com>
JBoss Performance Team
_______________________________________________
infinispan-dev mailing list
infinispan-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/infinispan-dev