[infinispan-dev] Infinispan Javascript client 0.1.0 is out now!
Radim Vansa
rvansa at redhat.com
Tue Feb 23 11:27:39 EST 2016
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 <rvansa at 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 <rvansa at 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 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
>>> _______________________________________________
>>> 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
>
> _______________________________________________
> 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
More information about the infinispan-dev
mailing list