Benchmarking Falcor.js

In the past few weeks I was figuring out how to solve a problem of a chatty communication between client and server considering that we are close to the release and I have already got few ideas in mind to improve the product I’m working on right now.

Thinking to possible solutions I thought to search online few different approaches that could help me out to solve the problem, at the beginning I was thinking to refactor the REST APIs in order to create them closer to what the UI needs (backend for frontend pattern) but then I remembered that I had bookmarked few projects that could help me out to implement this pattern without reinventing the wheel.
So on friday night I started to investigate Falcor.js, a library made by Netflix that was trying to solve exactly my same problem and they honestly solve the issue in a really smart way.

Let’s imagine you have a client that needs to call several REST end points in order to aggregate the data for a specific view, independently from how large is the amount of data to retrieve you have to bear in mind few other drawbacks like:

  • latency
  • no caching on specific data because they are real time data or tight to a specific user
  • amount of data to display in a view (maybe without a paging API available to split them in several views)
  • pre-flight calls for CORS end points
  • internet connection speed (mobility vs home vs office)
  • content negotiation

All of these, and probably many others, could be causes of a bad user experience and quite often we postpone to address these problems after the release of our online products.
So if we can minimise the impact in somehow we could provide a better user experience and therefore our products could be faster, more interesting and raise a good success with our users also when they have poor connection signal on their favourite device.

Here is where Falcor.js comes in support, in fact with Falcor we can minimise the amount of calls to specific end points because this library is leveraging the idea of a unique data model that could be interrogate by our clients asynchronously via Falcor APIs optimising the amount of queries to it under the hood.
The query system allows not only to fetch data from Falcor model but also to get only the data you need to use in a specific view.

services-diagram
From Falcor.js website

Looking at the image above you can spotted immediately the possible problem that Falcor solves brilliantly with a unique model.
In fact the Router is aggregating data from different end points and therefore the client can request exactly what needs in a nice and simple way.

Let’s try to explain how the system works first:

falcor-end-to-end
From Falcor.js website

The client will create a connection to a JSON model using the HTTPDataSource provided by Falcor.js client library that will allow to start the connection between the client and the backend data model.
On the backend a Falcor router is created and inside this instance there will be the description of the different queries available and what are the data to return as router system.
Doing this each client will download only the data that effectively needs to render the page and not an element more (sometimes reducing drastically the amount of data to load).
Also each client won’t need to interrogate ad hoc services for retrieving ad hoc data created for it but will just query the same data model created for the entire application only querying different end points.
As you can see from the diagram above this part sits between the client and your backend system creating a middleware that could be use only for specific end points or for the entire application.

Another interesting characteristic of Falcor is how it can optimise the query to the data model, in fact activating the batch mode, Falcor will gather all the queries to a specific route in a tick of your application performing all of them and possibly optimising to a unique roundtrip the requests instead of multiple roundtrips!

Last but not least Falcor allows you to query the APIs implementing a paging mechanism when you are iterating elements inside lists. For instance if you have an array of elements to display in your view but the APIs provided by the backend team don’t include any paging parameter, Falcor helps you via the query system, retrieving only a certain amount of elements via the paging mechanism.

So after watching the few videos available on Falcor and reading all the documentation in the website I started to experiment directly on the chatty issue I’ve got in my project.
I can’t really share the code I’ve used for my spike mainly because I’m using the product end points but I can share with you some benchmarks and thoughts on that for now.

Currently the catalogue I’m working with is composed by 5 calls to 5 different end points in order to display THE catalogue inside the view.
There is also a timer where every few minutes these 5 calls are performed again in order to retrieve new data that possibly could refresh the products available for the user inside the page.
Obviously behind the scene the application is doing several other calls in order to synchronise its status and performing some checks, but for now let’s focus only on the catalogue part.
I extracted the 5 calls in a simple HTML page replicating the current situation in the product and gathering some metrics to understand which was the starting point and how much Falcor would be able to improve the situation.
These are the benchmark I’ve retrieved for 5 XHR calls to different end points when the data are cached and when they aren’t:

NO CACHED XHR (after 5 calls):
average time on 10 tests ~678ms
average kb on 10 tests ~111kb

CACHED XHR (after 5 calls):
average time on 10 tests ~126ms
average kb on 10 tests ~3.1 kb

Then what I did was implementing a Node.js gateway where using the Falcor Router and the Falcor model I was able to query only the data I needed (and not downloading the entire JSON with information not needed for that specific view), I’ve optimised the query to the Falcor model via batching requests and these are the results with Falcor in place in front of the product APIs:

NO CACHED WITH FALCOR (Falcor optimise the 5 calls to only 2 calls):
average time on 10 tests ~32ms
average kb on 10 tests ~5 kb

CACHED WITH FALCOR (Falcor optimise the 5 calls to only 2 calls):
average time on 10 tests ~10ms
average kb on 10 tests ~406 bytes

This is really a good performance boost considering the amount of data we downloaded by default that are now optimised via Falcor queries; several roundtrips saved because of the batching requests optimisation natively available in Falcor APIs and the nice asynchronous implementation to fetch data from the unique model.

I’ve to admit that I was really surprised and I believe sooner than later I’ll introduce Falcor.js in production because it can really simplify the pipeline of work and provide great benefits to your applications in particular when you are targeting different low end devices like in my project.
Another think that would be good to invest time on(maybe another weekend :P) is GraphQL, the main “competitor”, maybe I’ll be able to do a 1 to 1 comparison based on the same problem and see which is the best library for a specific problem.

Meanwhile if you want to start playing with it I recommend Falcor website and I encourage you to keep an eye on this blog because I’d like to share in another post more technical information about Falcor that will allow you to understand how easy is working with it.

 

Cycle.js a reactive framework

I had the chance to spend quite few evenings with Cycle.js preparing my presentation for JSDay 2016 and I have to admit that I had quite a lot of fun so I decided to share my experience in this post.

I’d suggest first to take a look to my previous introduction to reactive programming just to cover the basics if you are not familiar with this paradigm.

Cycle.js is an incredible light framework that allow you to work in a reactive fashion way. As mentioned on all my talks regarding this topic, the initial entry level is a little bit higher than other frameworks if you are not familiar with Reactive concepts like hot and cold observables for instance and Functional concepts like pure functions.
Cycle puts the functions as first class citizen for the entire framework, having a previous knowledge of reactive and functional paradigms definitely it helps to speed up working with this framework.
Let’s start to see how it works from an eagle eye perspective:

Screen Shot 2016-05-22 at 11.37.17

This image above represent the main concept behind Cycle where we have a loop between the a main method, that receives as input a read effects (sources), and the “external world” that receives some write effects as output (sinks).
The side effects generated by the main function will be handled by the “external world” inside drivers that will communicate with the external world.

Cycle in practice

 

Cycle.js allows you to work with an interesting architecture created ad hoc for reactive programming called MVI (Model View Intent), I wrote an extensive article on this topic and I suggest to read it because the architecture is really interesting leveraging new concepts like the communication between objects via observables.

mvi

There is an interesting read in the Cycle website that explains how MVI works in the official website.

For the JSDay I prepared a simple example in MVI with Cycle just to show how simple is working with this architecture and with Cycle framework.
The example is a real time monitor for London Underground trains showing the position of each train and the expected arrival to their destination.

Screen Shot 2016-05-11 at 11.52.07

You can find the project on my github account

The application is mainly composed by 4 main areas:

  • Main.js is the entry point of our application where I’m instantiating Cycle run loop and I’m adding the hot reloading module for Cycle.js
  • App.js where there is the business logic of the application written in MVI (mvi-refactor branch)
  • Networking.js where I’m handling the HTTP request and response made via HTTPDriver
  • Template.js that represents the renderer object made with hyperscript (default virtual-dom library present in Cycle)

The App.js is where the business logic of the application sits with the division of competences between Model – View – Intent.
I warmly suggest to have a read to my article on MVI as mentioned before in order to understand how MVI works.

export default function app(_drivers){
   const response$ = networking.processResponse(_drivers.HTTP);
   const actions = intent(_drivers.DOM);
   const state$ = model(response$, actions);
   const vtree$ = view(state$);
   const trainsRequest$ = networking.getRequestURL(actions.line$, DEFAULT_LINE);

   return {
      DOM: vtree$,
      HTTP: trainsRequest$
   };
}

the interesting part here is how I’ve divided the interaction between different actors present in the app inside the main method.
All the constants that ends with $ symbols are observables (this is a simple convention to immediately recognise which variable is an observable and which is not).
The app method has a unique argument (_drivers) and it returns an object containing 2 observables that will be handled by the outside world via drivers (check Main.js to see where I’ve instantiated the DOM and HTTP drivers).

Then I’ve created the networking object that is handling the interaction between an end point and the application.
response$ is the observable where I’m going to store the service response and trainsRequest$ is where I’m defining the request using the tube line chosen by the user in query string (check Networking.js for that).

Last but not least I’m creating the MVI structure where the only point of communication between these pure functions is an observable or a collection of observables.
That would help me to testing easily the application, encapsulating properly the behaviours of each part and having a unidirectional flow of information that are flowing inside the application or component.

I’d like to bring your attention now to how the view is handled in Cycle.js, the view is generating a virtual tree of elements that will be rendered by a third party library like Hyperscript or React.
It’s not a case that Cycle is using a render library that implements the virtual-dom concept because, as we describe at the beginning, Cycle works with loops so having a diff algorithm that update the DOM only when needed it’s a great boost performance wise for the entire application and it removes some complexity to handle on the developers side.

export default function getBody(results){

   let selectedLine = results[0].length > 0 ? 'Selected line: ' + results[0] : "";
 
   return div(".container", [
      h1("#title", ["Reactive Live London Tube trains status"]),
      select("#lines", [
         option({ value: 'piccadilly' }, ["Piccadilly line"]),
         option({ value: 'northern' }, ["Northern line"]),
         option({ value: 'bakerloo' }, ["Bakerloo line"]),
         option({ value: 'central' }, ["Central line"]),
         option({ value: 'district' }, ["District line"]),
         option({ value: 'circle' }, ["Circle line"]),
         option({ value: 'victoria' }, ["Victora line"]),
     ]),
     h3("#selectedLine", [selectedLine]), 
     renderTrainsData(results[1])
   ]);
}

Just to give you an idea, I brought the entry function that generates the application view, after defined few static elements like the dropdown and few title elements, I’m going to call another function that is returning the results to display in the main view.
In renderTrainsData function I’m returning the elements splitting the different domain objects across 3 other functions:

function getTrainData(data){
   return li(".train", [
      div(".train-data", [
        p(".stationName .col", [span("station: "), data.stationName]),
        p(".platform", [span("platform: "), data.platformName]),
        p(".current-location", [span("current location: "), data.currentLocation]),
        p(".arrival-time: ", [span("expected arrival time: "), moment(new Date(data.expectedArrival)).format("HH:MM - Do MMM YYYY")])
      ]
   )])
}

function getDestinationStation(data){
   return div(`.destination-station .${data.lineId}`, [
       h2(data.destination),
       ul(".destination-trains-available", data.trains.map(item => getTrainData(item)))
   ]);
}

function renderTrainsData(data){
   return div(".all-stations", data.map(item => getDestinationStation(item)));
}

As you can see is very easy to understand and the code becomes very readable for anyone, in particular when we are writing meaningful function names.
I’ve created also some simple CSS IDs and classes defined as first parameter of each HTML element just for the curiosity to see a basic integration between hyperscript and CSS.

Wrap Up

Cycle.js is showing a new approach to the Javascript community with a lot of good ideas and a growing community that is following and improving the framework.
I can’t say that would be the most used framework for the next year considering how much React+Redux and Angular 2 are succeeding in the front end scene, but I believe that with Cycle you can still create great applications often with less and well structured code compared to other frameworks.
I’ll definitely continue to go ahead with it and possibly to contribute as much as I can to this project and Rx.js as well, because I strongly believe in the future of reactive programming paradigm and the people behind it.

 

How to Dockerize your Node application

Today I’d love to share how to wrap a Node microservice or monolithic application inside a Docker container.
I assume that you’ve already installed Docker, boot2docker and Node in your machine.
If you don’t, please check the official Docker page and Node page and after picking your operating system follow the instructions.

I’ve created a simple Node application with Hapi.js that once called returns the classic “hello world” message as response, obviously you can have a way more complex application as well, my main purpose here is talking about how to setup Docker with your Node.js application.

In order to wrap your application inside a Docker container you need to create a Dockerfile, this file is basically defining the setup for the environment where your application will run.
Checking the Docker containers currently available on Docker hub, you can see for Node the official container page that will allow you to pick the right Node version for your application.

Screen Shot 2016-04-03 at 17.01.57

As you can see there are many different Node containers available, you can also use other solution like using ubuntu, fedora or centOS as base OS where your node application is going to run but I preferred to use the official one because my server side application doesn’t require any particular configuration.
For this example we are going to use the 5-onbuild that basically is doing the “dirty job” for us, obviously this is a sample application but you can customise your container as you prefer.
What the onbuild version is doing is basically:

  • creating a directory of the application inside the container
  • copying package.json in that folder
  • running “npm install” command
  • running “npm start” command

It’s fundamental to define inside the package.json all the dependencies and the start script otherwise the application is not going to work inside the container.

Inside our Dockerfile we are going to write:

FROM node:5-onbuild
EXPOSE 8080

So basically we are inheriting all the steps described above regarding the onbuild Dockerfile plus we are exposing the port 8080 that is the one used by our Node application:

const server = new Hapi.Server();
server.connection({ port: 8080 });

It’s a best practice for any Dockerfile starting always with a FROM command and reusing the images that are already created by the community on Docker hub so remember when you want to try something different check always what’s available on Docker hub.

Good so now let’s package our container and try if it works correctly.
In order to build the container we’ll need to run the following command:

docker build -t <username>/<applicationName> .

Basically here we are saying to docker to dockerize the entire folder application (dot at the end of the command)  and the container will be called <userName>/<applicationName>
This is another Docker best practice, potentially you can call your container as you prefer but a pattern is adding first your Docker username then slash (“/”) then your application name:

docker build -t lucamezzalira/docker-hapi .

Not let’s try if it works:

docker run -p 49160:8080 -d lucamezzalira/docker-hapi

With this command we are running our container, therefore our Node application, mapping the port 8080 of the container to the port 49160 of the host.
You can check easily if the application is working correctly just typing docker ps in your console, you should see something like that:

Screen Shot 2016-04-03 at 17.29.48

So now, because I’m working on Mac, I need to retrieve the boot2docker IP and check if in the port 49160 I’m able to see my hello world application up and running.
In order to do that I’ll run the command:

boot2docker ip

That should return the external IP where my application  is running, you can also see which is the container IP using the command:

docker inspect CONTAINER ID (for example: docker inspect afb5810152f6)

The container ID is easily retrievable via docker ps (first column in the picture above).
This command will return a JSON file with a lot of information related to the container.

So now that I’ve the IP where my application is running and the related port  I can type inside my bowser the address and see the result!

Screen Shot 2016-04-03 at 17.36.00

Obviously you can also map that IP to etc/hosts file adding something more meaningful like boot2docker or whatever name your think is more appropriate!

If you want to download from Docker hub the container I’ve prepared for this post just type:

docker pull lucamezzalira/docker-hapi

This is a very basic introduction to Docker world and Node, I’m working on a sample microservices application that will involve few interesting concepts and pattern, so keep an eye on this blog😉

Hot and Cold observables

One important thing to understand when you are working with Reactive Programming is the difference between hot and cold observables.
Let’s start with the definition of both types:

Cold Observables

Cold observables start running upon subscription: the observable sequence only starts pushing values to the observers when subscribe is called.

Values are also not shared among subscribers.

Hot Observables

When an observer subscribes to a hot observable sequence, it will get all values in the stream that are emitted after it subscribes.

The hot observable sequence is shared among all subscribers, and each subscriber is pushed the next value in the sequence.

Let’s see now how these 2 different observables are used across a sample application.

Using the same application I started to describe in my previous blog post, we can spot in the main class some code that is commented.
The first part represent how a cold observable works, so if you try to have the following code inside App.js you can immediately understand what’s going on when an observer subscribes to a cold observable:

let engine = new BallsCallSystem(); 
let t1 = new Ticket("t1", engine.ballStream); 

setTimeout(()=>{
    let t2 = new Ticket("t2", engine.ballStream);
}, 5000);

engine.startGame();

Our game engine instead has the following code in order to share the balls called across the tickets:

let stream = Rx.Observable
    .interval(INTERVAL)
    .map((value) => {return numbersToCall[value]})
    .take(TOTAL_CALLS);
 
this.published = stream.publish();

As you can see when we start the game there is only 1 ticket bought by the user, then after 5 seconds the user bought a new ticket and in theory we should check if in that ticket all the numbers previously called are present or not.

coldObservables
But with cold observables when an observer subscribe, it won’t be able to receive the previous data but just the data since when it subscribed, completely broken the main purpose of our bingo game… we definitely need something different in order to work with it, potentially something that won’t completely change our game logic but that could be useful to fix the issue…

That’s where the hot observables come in!
The cool part of hot observables is that you can define how much data you want to buffer inside the memory, sometimes you need to store all of them (like in the bingo game) sometimes you need only the last 4-5 occurrences, but as you will see changing from a cold to an hot observables it’s a matter of 1 line of code!

Inside the same git repo, you can find a class called BallsCallSystemReplay, this class implement an hot observable, let’s see how much the code changed inside our game engine:

this.stream = Rx.Observable
   .interval(INTERVAL)
   .map((value) => {return numbersToCall[value]})
   .take(TOTAL_CALLS)
   .shareReplay();

Basically we removed the publish method after creating the stream (that was useful if you want to control when the observable starts to stream data) and we added shareReplay that is a method that transform a cold observable to an hot one sharing all the data pass trough the stream every time a new observer subscribe to it.

So now if we change the code in App.js in this way:

let engine = new BallsCallSystemReplay();
let t1 = new Ticket("t1", engine.ballStream);
 
setTimeout(function() {
    let t2 = new Ticket("t2", engine.ballStream);
}, 5000);

Now you can see that when the second ticket is bought after the game started, we’re going anyway to check all the values called by the engine without doing a massive refactor of our game logic! Below you can see when the second ticket subscribe to the hot observable, the first thing is going to receive are all the previous values called by the engine and then is receiving the data with a certain interval following the logic of the game.

hotObservables

Reactive Programming with RxJS

In the past 6 months I spent quite few time trying to understand Reactive Programming and how it could help me on my daily job.
So I’d like to share in this post a quick example made with RxJS just to show you how Reactive Programming could help when you are handling asynchronous data streams.

If you are not familiar at all with these concepts I’d suggest to watch first my presentation on Communicating Sequential Process and Reactive Programming with RxJS (free registration) or check the slides below.

For this example I thought to create a basic bingo system that I think is a good asynchronous application example that fits perfectly with the Reactive Programming culture.
I won’t introduce in this blog post concepts like hot and cold observables, iterator pattern or observer pattern mainly because all these theoretical information are present in the webinar and the slides previously mentioned. 

You can clone the project repository directly from my git account.

Let’s start talking a little bit about the engine, basically a bingo system is composed by an engine where the numbers are called every few seconds and shared with the users in order to validate in which ticket bought by the user the number called is present.
For this purpose working with observables will facilitate the communication and the information flow between the engine and the ticket objects.
In BallsCallSystem class, after setting up the object creating few constant that we’re going to use inside the core engine, we’re going to implement the core functionality of the engine:

let stream = Rx.Observable
              .interval(INTERVAL)
              .map((value) => {return numbersToCall[value]})
              .take(TOTAL_CALLS);

These few lines of code are expressing the following intents:

  1. we create an observable (Rx.Observable)
  2. that every few milliseconds (interval method)
  3. iterate trough the interval values (incremental value from 0 to N) and return a value retrieved from the array numbersToCall (function described inside the map method)
  4. and after a certain amount of iteration we need to close the observable because the game is ended (take method) so all the observer will stop to execute their code

If we compare with an imperative programming implementation made with CSP (communicating sequential processes) I’ll end up having something similar to this one:

this.int = setInterval(this.sendData.bind(this), 3000);
[....]
sendData(){
   var val = this.numbersToCall[this.counter];
   console.log("ball called", val);
 
   csp.putAsync(this.channel, val);
   this.counter++;
 
   if(this.counter > this.numbersToCall.length){
      clearInterval(this.int);
      this.channel.close();
      console.log("GAME OVER");
   }
 }

As you can see I needed to express each single action I wanted to do in order to obtain the core functionality of my bingo system.
These 2 implementations are both solving exactly the same problem but as you can see the reactive implementation is way less verbose and easy to read than the imperative one where I’ve control of anything is happening inside the algorithm but at the same time I don’t really have a specific reason to do it.

Moving ahead with the reactive example, when we create an observable that streams data we always need an observer to retrieve these data.
So now let’s jump to Ticket class and see how we can validate against a ticket the numbers called by the engine

First of all we pass the observable via injection to a Ticket object:

let t2 = new Ticket("t2", engine.ballStream);

Then, inside the Ticket class we subscribe to the observable and we handle the different cases inside the stream (when we receive data, when an error occurs and when the stream will be terminated):

obs.subscribe(this.onData.bind(this), this.onError.bind(this), this.onComplete.bind(this));
onData(value){
    console.log("number called", value, this.tid);
    if(this.nums.indexOf(value) >= 0){
       this.totalNumsCalled.push(value);
       console.log(value + " is present in ticket " + this.tid);
    } 
 }
 
 onError(err){
    console.log("stream error:", err);
 }
 
 onComplete(){
    console.log("total numbers called in " + this.tid + ": " + this.totalNumsCalled.length);
    console.log(this.totalNumsCalled);
 }

Also here you can notice the simplicity of an implementation, for instance if we are working with React it will be very easy to handle the state of an hypothetical Ticket component and create a resilient and well structured view where each stream state is handled correctly.

An interesting benefit provided by reactive programming is for sure the simplicity and the modularity at the same time how our implementations are working.
I would really recommend to spend sometime watching the webinar in order to get the first approach to Reactive Programming and to understand better the purpose of the example described briefly above.

Scotch on the Rocks 2010

It’s finished!!! DAMN!

SOTR 2010 is end, I hope to come again next year, but now I want to share with you my experience here in London.

SOTR was organized at TigerTiger club near Piccadilly circus in the heart of London and believe me, It’s my first time that I take part in a conference where stop for a couple of days a club! That’s totally crazy, but this is SOTR and I love it! (Obviously free drink inside ;P)

Location a part, sessions were pretty cool, I really appreciate Aral and Serge one, the first was an inspire session based on clients UX and I grabbed very cool suggestions; Serge’s session was about AIR 2 and Flash Player 10.1 on Android devices… I really love those stuff!
It was impressive a performance benchmark where the same animation created with HTML and JS (7fps), another made with HTML 5 and canvas (9fps) and one made with Flash Player 10.1 (25fps !!! I really love Flash Platform) obtains different results on Android… and what results!!!

I was at SOTR also to speak about AIR 2 printing API, AlivePDF and PurePDF, I made an inspire session that allow you to have the right solution when someone (your boss maybe?!) ask you to create data reports or paper documents in a Flex RIA or AIR application.
My English a part, I think that people enjoy case history part and first twitter messages are agree with me, so believe me guys at SOTR, thank you so much for your time.
Finally in my session I shared my “thoughts” about HTML 5, Apple and so on (many photos on this slide, I was sure that you appreciate it! :D).

You can download all the stuff made for AIR & Printing session directly from this blog and if you weren’t in London and you want ask me more details about this cool shit, feel free to contact me or leave a comment at this post!

Ok, it’s time to come back to reality but before that I must say a big THANK YOU to Andy Allan that organize this amazing event, Cyril and Guust (and his girlfriend) for the great time spent together in London talking about Coldfusion and our beautiful countries.

Second day at Flash on the Beach 08… Flash 10 on IPhone

Second day is finished, but it was very intensive!
I saw lots of interesting session, first of all Mr. Aral Balkan that showed us how to have fun with our work and that we must take time to experiment and try new languages, very interesting session.

Then, my favourite, Adobe Town Hall, where they said: “Yes we are working on Flash 10 on iPhone!”.
I hope that they don’t put a “slim” version without important API like the newest that allow to work with local files with Flash Player in a browser.
I asked also if with AIR 2 they will solved the problem of interaction with others applications embedded on a mobile phone and if it update itselfs without download a new firmware… they said… “Open Screen Project solved the second issue and the first one… yes we are working on this way”.
Great news for mobile developers!

Then I saw Grant Skinner with a cool sesson about  what a Flash developer should know… 

Peter Elst talked about AIR api and show interesting things with Merapi Projects and Adobe AIR… the speech to text sample was amazing!

Lee Brimelow showed us about new Adobe product releases like Flex 4, new features of Flash CS4 and so on, it’s an amazing speaker because he show stuff with a fun.. like a joke… cool!

Tomorrow I will attend the last day, there will be lots of interesting things to take a look… Nicolas session for example… see you tomorrow guys