AFAIK, we're stuck with `function(client) { return ... ;}` since we need to 
support ECMAScript 5.

ECMAScript 6 brings in lambda syntax which will make this more palatable:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Your suggestion would not really work since it would mean passing a value 
instead of a function, and we need the latter to be able to chain functions 
lazily.

Cheers,
--
Galder Zamarreño
Infinispan, Red Hat

> On 23 Feb 2016, at 17:27, Radim Vansa <rva...@redhat.com> wrote:
> 
> Thanks, though it was pretty clear even after your first reply.
> 
> One more thing: it seems to me that there is certain redundancy in 
> declaring
> 
> function(client) { return ... ;}
> 
> where only the ellipsis is the business logic. I would recommend 
> including helper with higher-order functions, that would give remove the 
> need for the above when you just called ispn API, please see how I've 
> modified
> 
> var put = before.then(function() { return client.put('k', 'v'); }); // 
> from [2]
> 
> into
> 
> var put = before.then(cache().put('k', 'v')); // [3]
> 
> ([3] includes stub of the helper). Or is this too non-JS-ish (TBH I 
> haven't tested if that is valid JS)?
> 
> Radim
> 
> [3] https://gist.github.com/rvansa/ba5be94ba3bf7ae39a91
> 
> On 02/23/2016 04:35 PM, Galder Zamarreño wrote:
>> Radim, once again thanks for the invaluable feedback.
>> 
>> As promised, I will ammend the README to make it much more clear but I found 
>> a very easy example that I can show here as I was working on the JS client 
>> testsuite.
>> 
>> Imagine this scenario: I want to verify that after doing a put 'stores' 
>> statistic goes up by 1. The obvious thing to do here is this:
>> 
>> 1. invoke stats to find out initial 'stores' value, then...
>> 2. invoke put, then...
>> 3. invoke stats again and compare with initial 'stores' value.
>> 
>> Using Promises, this can be coded in two different ways. The first one is 
>> using nesting, e.g. [1]. This is a bit ugly but this is how you'd do have to 
>> do it if you were using function callbacks instead of Promises.
>> 
>> The alternative is to chain Promises, taking into account that Promise's 
>> then() return a Promise or a directly value from within it. Here's an 
>> alternative solution that reads more cleanly [2].
>> 
>> Here we can see how the first then() callback returns a value directly, 
>> which are the statistics before the put operation. The next two .then() 
>> calls return Promises, first a promise for the put, and the second a promise 
>> of the stats retrieved after put operation.
>> 
>> Finally, we call Promise.all() which takes N promises and calls back .then() 
>> when all those promises have been fullfilled, and then passes the results of 
>> those promises as parameter. Within this last .then() callback, we can do 
>> the necessary assertions compare before and after stastistic values.
>> 
>> Hope this clarifies things further.
>> 
>> Cheers,
>> 
>> p.s. 'stats' operation support is work in progress.
>> 
>> [1] https://gist.github.com/galderz/65ed0b2a4e02b8f4e0c1
>> [2] https://gist.github.com/galderz/c349d3aa64a39684d7d7
>> --
>> Galder Zamarreño
>> Infinispan, Red Hat
>> 
>>> On 19 Feb 2016, at 11:17, Radim Vansa <rva...@redhat.com> wrote:
>>> 
>>> All right, this example looks much better. And the ability to use native
>>> variables rather than keys into the session is much more comfortable.
>>> Thanks for the explanation!
>>> 
>>> Radim
>>> 
>>> On 02/19/2016 10:53 AM, Galder Zamarreño wrote:
>>>> --
>>>> Galder Zamarreño
>>>> Infinispan, Red Hat
>>>> 
>>>>> On 19 Feb 2016, at 10:31, Radim Vansa <rva...@redhat.com> wrote:
>>>>> 
>>>>> Just checked the readme, and TBH I wouldn't be too enthusiastic about
>>>>> the deep nesting of chained operations (basically each follow-up
>>>>> operation requires further level of nesting). Is that the way async
>>>>> handlers are usually written in JS?
>>>> I think the README I've produce is a bit confusing, I'll work to improve 
>>>> for future versions. In the mean time, let me explain this:
>>>> 
>>>> The reason Promises are used instead of callback parameters is precisely 
>>>> to avoid this kind of deep nesting.
>>>> 
>>>> The code below shows 4 (but could be N really) operations which are 
>>>> chained only 2 levels deep:
>>>> 
>>>> connected.then(function(client) {
>>>>    ... <- Do something with the client
>>>>    var putCall = client.put('key', 'value');
>>>>    var getCall = putCall.then(function() {
>>>>    return client.get('key');
>>>>    });
>>>>    var containsKeyCall = getCall.then(function() {
>>>>    return client.containsKey('key');
>>>>    });
>>>>    var removeCall = containsKeyCall.then(function(contains) {
>>>>    return client.remove('key');
>>>>    })
>>>> });
>>>> 
>>>> The key aspect of this is that no matter how many operations you want to 
>>>> chain together, the nesting levels are constant. You could have 100 
>>>> operations chained together, you would still only have 2 levels deep.
>>>> 
>>>> The README file might not make this so obvious and hence I'll work to 
>>>> improve on that.
>>>> 
>>>> Also, the API above is using Promise API which will be standard in ES6. 
>>>> Even though Infinispan JS Client is based on ES5, the `promise` module 
>>>> sticks to the forthcoming standard Promise API, and hence we're using 
>>>> something that in a few years will be standard, which is a good thing. 
>>>> Conceptually, Promise API is similar to Scala's Future or Java's 
>>>> CompletableFuture.
>>>> 
>>>> The other alternative that's used in Node.js is passing callbacks as 
>>>> parameters to each put/get call... and that does cause very deep nesting, 
>>>> because if you want to chain 100 operations together, you need 100 nested 
>>>> calls! Plus not centralised error handling, and many other disadvantages.
>>>> 
>>>>> Last few weeks I am working with Gatling and the syntax to describe
>>>>> scenarios = chained operations is quite nice (though it's Scala). Would
>>>>> it be possible to have a syntax like this?
>>>>> 
>>>>> connected
>>>>>     .then(function(client) {
>>>>>         client.put('key', 'value');
>>>>>     .then(function(client) {
>>>>>         client.get('key').use(function(value) {
>>>>>             console.log(':get(`key`) = ' + value);
>>>>>         }).save('p0'); // this would be the same as use(function(value)
>>>>> { client.save('p0') })
>>>>>     }.
>>>>>     .then(function(client)) {
>>>>>         client.remove('key', client.load('p0')).use(function(success) {
>>>>>             console.log(':remove(`key`) = ' + success);
>>>>>         });
>>>>>     }).exec();
>>>> Independent of the correctness of the syntax, this API can be split in 
>>>> several concepts:
>>>> 
>>>> 1. The first one is that for those operations that have not a return, e.g. 
>>>> a put, you're passing on the client instance. I think that sounds fine.
>>>> 
>>>> 2. For your API to work, get() would need to return something other than 
>>>> Promise that has a use/save methods. I'm very reluctant to do anything 
>>>> like that since it's not standard and would require more upfront 
>>>> understanding from the user. Right now, we provide a Promise, a concept 
>>>> that's very well understood in the JS community and that will become 
>>>> standard in ES6.
>>>> 
>>>>> Note that I've used conditional remove to demonstrate load of previously
>>>>> saved value. Also, I am mixing the concept of client = cache and
>>>>> session, but maybe these could go to single object.
>>>>> 
>>>>> Just my 2c
>>>>> 
>>>>> Radim
>>>>> 
>>>>> On 02/18/2016 12:04 PM, Galder Zamarreño wrote:
>>>>>> Hi,
>>>>>> 
>>>>>> Following on Tristan's anouncement, we've also released Infinispan 
>>>>>> Javascript client version 0.1.0. You can read all about it here:
>>>>>> http://blog.infinispan.org/2016/02/infinispan-javascript-client-010-is-out.html
>>>>>> 
>>>>>> Cheers,
>>>>>> --
>>>>>> Galder Zamarreño
>>>>>> Infinispan, Red Hat
>>>>>> 
>>>>>> 
>>>>>> _______________________________________________
>>>>>> infinispan-dev mailing list
>>>>>> infinispan-dev@lists.jboss.org
>>>>>> https://lists.jboss.org/mailman/listinfo/infinispan-dev
>>>>> -- 
>>>>> Radim Vansa <rva...@redhat.com>
>>>>> JBoss Performance Team
>>>>> 
>>>>> _______________________________________________
>>>>> infinispan-dev mailing list
>>>>> infinispan-dev@lists.jboss.org
>>>>> https://lists.jboss.org/mailman/listinfo/infinispan-dev
>>>> _______________________________________________
>>>> infinispan-dev mailing list
>>>> infinispan-dev@lists.jboss.org
>>>> https://lists.jboss.org/mailman/listinfo/infinispan-dev
>>> 
>>> -- 
>>> Radim Vansa <rva...@redhat.com>
>>> JBoss Performance Team
>>> 
>>> _______________________________________________
>>> infinispan-dev mailing list
>>> infinispan-dev@lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/infinispan-dev
>> 
>> _______________________________________________
>> infinispan-dev mailing list
>> infinispan-dev@lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/infinispan-dev
> 
> 
> -- 
> Radim Vansa <rva...@redhat.com>
> JBoss Performance Team
> 
> _______________________________________________
> infinispan-dev mailing list
> infinispan-dev@lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/infinispan-dev


_______________________________________________
infinispan-dev mailing list
infinispan-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/infinispan-dev

Reply via email to