[infinispan-dev] Native Infinispan Multimap support
Galder Zamarreño
galder at redhat.com
Thu Apr 13 17:31:03 EDT 2017
--
Galder Zamarreño
Infinispan, Red Hat
> On 6 Apr 2017, at 11:04, Radim Vansa <rvansa at 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 at redhat.com
>> <mailto:rvansa at 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 at redhat.com
>> <mailto:karesti at redhat.com>
>>> <mailto:karesti at redhat.com <mailto:karesti at 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/vertx/ext/cluster/infinispan/impl/InfinispanAsyncMultiMap.java
>> <https://github.com/vert-x3/vertx-infinispan/blob/master/src/main/java/io/vertx/ext/cluster/infinispan/impl/InfinispanAsyncMultiMap.java>
>>>
>>> [3]
>> https://gist.github.com/karesti/194bb998856d4a2828d83754130ed79c
>> <https://gist.github.com/karesti/194bb998856d4a2828d83754130ed79c>
>>> _______________________________________________
>>> infinispan-dev mailing list
>>> infinispan-dev at lists.jboss.org
>> <mailto:infinispan-dev at lists.jboss.org>
>> <mailto:infinispan-dev at lists.jboss.org
>> <mailto:infinispan-dev at 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 at lists.jboss.org
>> <mailto:infinispan-dev at lists.jboss.org>
>>> https://lists.jboss.org/mailman/listinfo/infinispan-dev
>> <https://lists.jboss.org/mailman/listinfo/infinispan-dev>
>>
>>
>> --
>> Radim Vansa <rvansa at redhat.com <mailto:rvansa at redhat.com>>
>> JBoss Performance Team
>>
>> _______________________________________________
>> infinispan-dev mailing list
>> infinispan-dev at lists.jboss.org <mailto:infinispan-dev at 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 at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/infinispan-dev
>
>
> --
> Radim Vansa <rvansa at redhat.com>
> JBoss Performance Team
>
> _______________________________________________
> infinispan-dev mailing list
> infinispan-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/infinispan-dev
More information about the infinispan-dev
mailing list