Hi all,
Dan and I had a chat to clarify some of these topics on IRC:
On 16 Jun 2015, at 14:36, Dan Berindei <dan.berindei(a)gmail.com>
wrote:
Hey Galder
I have finally read the proto8 code, and it looks quite good.
I do have some concerns about how the lambdas will interact with
distribution, because not every node performs conditional updates the
same way (at least not without total order):
1. In non-transactional caches, we will retry an operation if the
cache topology changes, and the second time around we don't want to
fail the operation if the key already has the correct value on the
primary owner.
^ Having discussed on IRC, this basically refers to whether
NonTxBackupOwnerBecomingPrimaryOwnerTest would work with a concurrent map implemented with
functiona map. The issue resolves around ValueMatcher and how it'd work if the
Infinispan does not know what the lambda does. For example, right now Infinispan cannot
make a difference between a lambda executing replace(K,V) and replace(K,V,V), and knowing
the difference between these two is needed to be able to select the correct value
matcher.
I don't have an answer for this yet. I'm porting the prototype to Infinispan and
when it's ready I'll look into NonTxBackupOwnerBecomingPrimaryOwnerTest running
with a concurrent map impl based on functional map.
2. In transactional caches, the conditional commands are only
checked
on the originator - all other owners apply the update unconditionally.
This makes the modifications idempotent, which then allows us to retry
the prepare as many times as necessary.
Similar issue to the one in the previous point. @Dan, can you pintpoint me to a particular
test to see how this would work?
Are you thinking of handling these differences in the lambdas
themselves, or maybe you have something else in mind?
^ Dunno yet.
For optimistic caches we also have the write skew check, is that
going
to be in the lambda? It's also be performed only on the primary owner
without TO, and on all the owners with TO...
^ Dunno yet.
I also have some questions about the MetaParams:
1. Do we really need MetaParam.Id? Couldn't we index the MetaParams by
their class?
We could potentially pass in the type of MetaParam class we are after, and do the array
search based on that. That might work without the need to add an extra ID Class. I'll
give that a try.
In case anyone is wondering, I wouldn't want to change the internal data structure in
MetaParams from an array to a hash map with Class and key type. On top of being quite
heavyweight, we'd need a weak hash map due to avoid leaking classes.
2. Do we really want such fine granularity? We could at least pair
Created/Lifespan and LastUsed/MaxIdle...
^ Makes sense, great idea :)
Cheers
Dan
On Mon, Jun 15, 2015 at 11:19 AM, Galder Zamarreño <galder(a)redhat.com> wrote:
>
>> On 10 Jun 2015, at 04:08, William Burns <mudokonman(a)gmail.com> wrote:
>>
>>
>>
>> On Tue, Jun 9, 2015 at 2:12 AM Galder Zamarreño <galder(a)redhat.com> wrote:
>>
>>> On 8 Jun 2015, at 10:57, Radim Vansa <rvansa(a)redhat.com> wrote:
>>>
>>> On 06/08/2015 10:41 AM, Dan Berindei wrote:
>>>> On Mon, Jun 8, 2015 at 10:37 AM, Galder Zamarreño
<galder(a)redhat.com> wrote:
>>>>>> On 5 Jun 2015, at 14:15, Radim Vansa <rvansa(a)redhat.com>
wrote:
>>>>>>
>>>>>> Is the marshalling comparison really fair? The
lambda-table-based
>>>>>> approach removes the need for serializing the class definition,
but in
>>>>>> practice - is the class definition always send around with each
RPC?
>>>>> ^ We've extensively added Infinispan Externalizers (which use the
Object Table approach shown in MarshallingTests) to reduce the size of our payloads, and
indeed for all those, no class definitions are sent around. So, as long as the types of
those are known to us, we can use such approach and avoid expensive serialization.
>>>>>
>>>>> NOTE: JBoss Marshalling's Externalizers are more expensive than
ObjectTable based approach but I can't remember why, it might be cos when you use
those, it might send the externalizer class' class definition around, but not sure.
>>
>> Yeah I believe that is correct. If we used the Infinispan Externalizers in
conjunction with the ObjectTable it should only pass around an Integer instead I thought,
so it should be much more favorable.
>>
>>>>
>>>> I think the Simple/DynamicClassTable classes in WildFly take care of
>>>> writing only a class id in the stream, instead of the class name, same
>>>> as our ExternalizerTable but using JBoss Marshalling's
Externalizers.
>>>> I don't know if there's any performance difference between the
two
>>>> approaches, but I assume they must be pretty similar.
>>>>
>>>>>> If
>>>>>> it is so, it seems like a serious flaw of the current codebase,
and not
>>>>>> something occurring only for the functional interface. In case
that we
>>>>>> keep the marshallers around, we should marshall second RPC (with
the
>>>>>> same lambda and another instance of the same captured class), and
look
>>>>>> on the diff rather than on the first serialized instance.
>>>>> ^ Hmmm, not sure what you mean there exactly.
>>>
>>>
>>> I meant that in case that the class definition is not sent with each RPC
>>> but only once/few times, we should not pay attention to the cost of
>>> sending the definition. As the test marshalls single RPC, the definition
>>> is always marshalled and accounted.
>>
>> ^ There are multiple tests in MarshallingTests, some of which marshall the
definition and others not, and I printed payload sizes:
>>
>> -> testObjectTableCapturingLambda payload is 43 bytes
>> testSerializableApplyLambda payload is 587 bytes
>> testExternalizerNonCapturingLambda payload is 160 bytes
>> testExternalizerCapturingLambda payload is 192 bytes
>> testNonCapturingLambdaAndSerializable payload is 501 bytes
>> testSerializableNonCapturingLambda payload is 597 byt
>> -> testObjectTableNonCapturingLambda payload is 3 bytes
>>
>> We're not going to go with any of the approaches that are over 100 bytes.
>>
>> I thought you could only have 1 ObjectTable defined per Marshalling
Configuration? Also it seems we would need to introduce a new facility for users to
register their own lambdas then, since they wouldn't be able to use our
Externalizers?
>
> Yeah, there can only be 1 ObjectTable. I haven't looked at in great detail the
integration part, but the examples show you can produce JBoss Marshalling Externalizers
for lambdas, so I don't see why we would not able to provide Infinispan Externalizers
for those and integrate into the current architecture.
>
> The only requirement would be that we'd need a fully defined class for the lambda
(as done in the example) we want to register, as oppose to be able to support on the fly
defined lambdas.
>
>>
>>
>> The most efficient one, as you'd expect, is the Object Table approach with a
Non-Capturing lambda where the size of the payload is 3 bytes. Clearly here no definition
is marshalled at all. Second one is the one where the lambda captures an external element
and hence that needs to be shipped every time.
>>
>>> So, if I understand that correctly, for user classes that do not
>>> register externalizers (I guess the registration is not automatic), the
>>> definition is sent around with each RPC, right?
>>
>> In that case yeah, to get that to work, you'd have to extend Serializable and
then you pay the penalty.
>>
>> This is the whole point why we came up with Externalizers and the framework
around it. If you want get running as quickly as possible, make whatever you want to ship
around extend Serializable but for ultimate performance, pre-registration of externalizers
is the way to go, and the same approach works just as well with
function/predicates...etc.
>>
>> Cheers,
>>
>>>
>>> Radim
>>>
>>>>>
>>>>>> Radim
>>>>>>
>>>>>> On 06/05/2015 11:44 AM, Galder Zamarreño wrote:
>>>>>>> Hi all,
>>>>>>>
>>>>>>> Thanks to all who contributed to the 1st draft revision.
We've taken all that input and created a separate Github project where we have
prototytped the 2nd draft of the advanced Java 8 based Infinispan API. The starting point
for you should be FunctionalMap [1].
>>>>>>>
>>>>>>> Here's a brief summary the major changes since the 1st
draft:
>>>>>>>
>>>>>>> 1. FunctionalMap has been separated into 3 sub-interfaces,
one for read only operations, one for write only operations, and a final one for
read-write operations. This separation makes it clear the purpouse of each operation and
adds a nice layer of type safety, e.g. you can't write with a read-only map, or you
can't read with a write-only map.
>>>>>>>
>>>>>>> 2. Param has been added, which is equivalent to Infinispan
Flag with the added benefit that it can carry values. There's no such example right
now but we could have in the future.
>>>>>>>
>>>>>>> 3. MetaParam has been added. This is a much more flexible and
extensible option compared to the current Infinispan's Metadata.
>>>>>>>
>>>>>>> 4. For operations returning mutiple returns, or working on
multiple elements, we've exposed something called Traversable, which is a subset of
Java's Stream. See its javadoc to find out more. Kudos to Will for his work on
distributed streams which has helped hugely with the design of Traversable.
>>>>>>>
>>>>>>> 5. Listeners have been added, again separating between
read-write and write-only listeners (JCache does not offer read-only listeners, e.g. cache
entry visited, and hence I think we'll drop our cache entry visited listener at some
point).
>>>>>>>
>>>>>>> 6. Will and I have explored marshalling aspects of lambdas,
and there are some interesting ways to reduce their costs by +90%! See MarshallingTest for
different options to marshall both capturing and non-capturing lambdas and their cost in
terms of payload sizes.
>>>>>>>
>>>>>>> Some final notes:
>>>>>>>
>>>>>>> * Please do read the javadocs, they contain a lot of
information on the reasons behind the design.
>>>>>>>
>>>>>>> * To find out how the different functional map variants are
used, look at ConcurrentMapDecorator and JCacheDecorator who use them to implement the
ConcurrentMap and javax.cache.Cache APIs respectively.
>>>>>>>
>>>>>>> * FunctionalMapTest contains examples on how to use
functional map variants for other operations which we deeply care about, e.g. Hot Rod
atomic version-based replace function.
>>>>>>>
>>>>>>> Special thanks to Mario Fusco (Java 8 In Action book
co-author) for his feedback throughout this 2nd draft design process.
>>>>>>>
>>>>>>> Cheers,
>>>>>>>
>>>>>>> [1]
https://github.com/infinispan/proto8/blob/master/src/main/java/org/infini...
>>>>>>> --
>>>>>>> Galder Zamarreño
>>>>>>> galder(a)redhat.com
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> 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
>>>>>
>>>>> --
>>>>> Galder Zamarreño
>>>>> galder(a)redhat.com
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> infinispan-dev mailing list
>>>>> infinispan-dev(a)lists.jboss.org
>>>>>
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
>>
>>
>> --
>> Galder Zamarreño
>> galder(a)redhat.com
>>
>>
>>
>>
>>
>> _______________________________________________
>> infinispan-dev mailing list
>> infinispan-dev(a)lists.jboss.org
>>
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
>
>
> --
> Galder Zamarreño
> galder(a)redhat.com
>
>
>
>
>
> _______________________________________________
> infinispan-dev mailing list
> infinispan-dev(a)lists.jboss.org
>
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
--
Galder Zamarreño
galder(a)redhat.com