 everybody first of all I'd like to apologize to not being able to come to Detroit to give this talking person I hope you're all having a great time at the conference I wish I was there but unfortunately it was not possible for me this year so today I will talk about Calix which is a new product that Light Bell has been building for I believe two years now and it's now available for use my name is Renat Kavokant and I'm principal engineer at LightBend work on the Calix team I guess you already have heard about Calix during your day at the reactive summit this year but nonetheless I'll give a short introduction to it explain our motivations to build such a product and then give a quick demo so you get a good understanding of how it feels to build a Calix application but before let's talk about ACA if you have been following the work of LightBend you know that we have been providing solutions to help developers to build reactive applications that's basic what ACA is ACA is the most powerful and successful actor system implementation of the JVM it has enabled developers all around the world to build reactive distributed systems without having to build everything from scratch it's our passion to make distributed system affordable and accessible to a broader audience distributed systems are hard to build and therefore we want to provide the tooling to make it accessible to any developer out there you can consider ACA as a runtime where you can implement your business logic and let ACA do the heavy lifting for you we provide very powerful tools to help you at this task the most powerful of them in my opinion is ACA cluster so think about that distributed databases providers like Cassandra or CochranDB or message broker providers think about Kafka they all provide cluster solutions in the cloud here with application service serving millions of users data needs to be spread sharded over many nodes and someone needs to ensure that data stays consistent but what about your application code can you also distribute your application well the easy path here is to build stateless applications and stateless means that you deploy as many instances as you need and you let the database layer take care of the consistency the common technique used in such a scenario is the classical optimistic look you read that from the DB and that data is a version and when you have to save it back you check if the server the version you have and the version that is in the DB is still the same if that's the case you can save it if not the process fails and needs to be retried or automatically or re-triggered by the user this technique works until it doesn't work anymore that's pretty much fine at small scale but but not when you need to serve millions of users this is when libraries like ACA becomes relevant you want to be able to build application that can take that kind of load without having to rely on a mystic lock and that's what ACA cluster does it will manage data over the cluster for you including persistence in a in a way that you don't need to resort to the mystic login so ACA is great it allows the valves to build extremely performant applications we love it however the story doesn't stop here while ACA gives you the tooling to build your own clusters applications you are still responsible for its deployment and to maintain the whole cluster infrastructure by that I mean you need to manage your database you need to manage your Kubernetes class you need to take care of security just to mention a few for those reasons we have built Kaliqs think about Kaliqs as a cloud runtime for reactive and distributed applications Kaliqs is building the idea with the idea of providing building blocks that you can use to implement your business logic without having to even think about how data will be persisted how that will be retrieved how your application will scale out how to manage your application cluster and so forth the philosophy is bring your code Kaliqs does the rest but how does that really work so in reality under the hoods we manage a Kubernetes cluster as you could imagine and in that cluster we run what we call execution cluster and there when you create a project it will live in that execution cluster you come and you deploy your service and on that slide the user function on the right side is your code the code that you're gonna write on the left side is a Kaliqs proxy and they are all together when you deploy your user function we put together with that your container your user function container we put the Kaliqs proxy and they will find each other they work together when a request comes in it goes to the proxy and the proxy delivers data to your user function that has the logic your user function will process it and send back to the proxy and the proxy saves the data so if we look a little bit closer what we have here is like your project that you're creating Kaliqs you deploy your code and they all go together with the proxy then as you go and you may need more resource power more computer power we scale out your service to a few other nodes but those are not stateless nodes they form an acupuncture so your code in one side they go always together with a proxy but on the proxy side so at some point you have let's say three pods each of them run in two containers on your code and what we call a sidecar but also the sidecar in Kubernetes terms for us we call it it's our proxy running there so your code does not make a cluster it's your service one side but the proxy that goes together with your code that are deployed together they do form a cluster now whenever we go back to the previous slides I have a line showing request coming in it goes to the proxy and if there is data that needs to be brought to memory it will take that from the database put in memory take the commands that just got in and send it to your code the state of your model and the commands your code will do what needs to be done and return to the proxy the new state if the state was updated if it's an event source entity it will return events as well that needs to be perceived so this dance between the proxy and the code happens on each time that there is a request keep in mind that the proxy is an aqua closer and it's managing the persistence and your code is just providing the logic to be applied on the data so you don't have to deal with persistence yourself but how how do you do that so you start by define your APIs using grpc definitions everything in calix today is about grpc then the calix tooling will generate class for you to implement so you define an entity an event source entity and we generate the skeleton for you you just have to implement it you can test it locally using unit test integration tasks or you can even run the application on your computer for that we're gonna you're gonna start your user function and also a proxy in a container in the docker container so the proxy and user functions are now running on your machine and you can just use them like to test manually if everything's work as expected the same happens integration tasks we also start a proxy and but then it's automated of course and once you are ready you'll deploy to calix but when you deploy to calix you don't deploy the proxy you only deploy your user function we provide a proxy it's included in the in the cloud infrastructure so calix has different components that you can use to build your system and the first one are event source entities they are backed by a journal and use commands and events to mutate its states basically commands get in are validated and events are emitted the emitted events are persisted by calix and then apply to the model updating its state event source involves capturing change to data as opposed to overriding existing values then we have also other kind value entities another kind of entities also persisted the difference here they are very similar to event source entities except that they don't emit events they are not event sourced they only persist the current state and that's why we call them value entities they are entities but the whole state is persisted the whole value that are in memory is persisted on each incoming command the model decides if the command must be rejected or accepted if accepted typically the command will mutate the states and the state in its whole is persisted next we have replicated entities they are also entities but they are not persistent they are uniquely identified by the given identified identifier but they don't go to the storage they stay they are distributor of the class so if you have your application has three nodes they will be in all of three of them in memory and you mutate in one node the change will be propagated the others eventually so they are eventually consistent but in memory data structures think about CRDT's and distributed eventually consistent distributed cache now those are entities and the two first entities they are persisted and but in all three case you cannot access them if you know their ID so you can always read the data if you know the ID but sometimes you need to do to do other kinds of queries you want to build a model that you can search that's not only based by ID for example you have many users and now you want to find to collect all users that has an email address that ends with gmail.com for instance for that you need to create an index and that's what the views gives to you so views are means to expose different representations of your model we can generate views based on the events of an event source entity or from the states change of value entity every time that the change of value entity the whole state is propagated to your view in the view implementation you get the value entity state and then you decide what to do and it allows you to query for the entities using different fields like using the email address instead of the unique ID and you are free to to to persist or to index the way you want you can say that you have a user and at the view side you also use the same model the user that you can just search by email or you can create another type you can say on the entity it's about the user but in the view it's a little bit different it's my user view for instance and there I don't store the password for the for example the last the last type of component we have are actions they are the most simple one they are stateless whenever you call an action it respond a new action to to receive the request and when it's finished the action just disappears so they are stateless if you put this stated in there it just get discarded it's each time and why you would use actions while there are few use case the first the most common one is the pure functions you get some inputs you produce you process data and you return that's just pure function computations you transform from A to B you can also use actions as a facade in front of your entities so the action receive the command from the exterior from from the outside and then you do some transformation and you forward it to the entity and the entity then responds to the to the action that then respond to the color color and the other options are you can also use actions to subscribe and to publish events so you can subscribe to to a topic Kafka or Google pops up and push data to Kafka Google pops up but you can also subscribe to event source entities events for instance and push into Kafka into on a on a topic and those are what we call the Felix components and there are a few more features we have first I already mentioned about the topics we have broken integration if you choose to deploy in Google clouds you get the integration with PubSub Google PubSub otherwise you can bring your own Kafka you configure it your Kafka's usually people use Kafka in the cloud as well they just configure Kafka in in calyx and then your calyx application can start to read and and push that into Kafka as well we have timers timers is a functionality that you can only use from an action and and timer you can say okay I want to make this call but not now in five minutes so you scan a call to be done in five minutes and this persists so if you shut down your machine your your notes at that moment and bring them back they will be executed we have ACL so access control is to you can annotate your methods say who who is allowed to to call it who I mean anyone on internet it's open to the internet it's only available for the internal service and so on and we have JWT support okay so I'd like to to write a little small application give a small demo and that's what we're gonna do to them right now I will use this color template for that it will create a value entity for us I call it calyx demo reactive summits I just skip the default options for the versions library versions and then the package I call it calyx demo okay we have here a project I would just quickly open that on visual studio because I want to show what is inside before I start to compile it it has just some protocols with the definition of my entity here is the state of my entity it's a counter well the template comes already with a model so you can play around with that the goal is that you delete that afterwards and use the templates to start your own model so we just keep going with the counter for convenience and it has commands message that can be sent to it increase decrease like increase the counter and the important bit here is that we have this information telling calyx that we need to we want to generate a value entity to manage that state the state in question is the counter state here I will add one extra field here I will say that this guy here has a name and what is that so we have the counter state is what is persisted and the current counter is what I returned when someone asked to get the counter so that's my external representation and just to make it a little bit different I'm adding here the name so next I will compile that but I will open it in IntelliJ because then it's more convenient to to work on it so let's let's have a look what got generated I have a main function which registered the counter and I have the counter that I have to implement so let's do it so the counter the first thing is that what is the empty state when there is no counter there when I have nothing my database and I want to send my first command what from where I start so I need an empty state or initial state and I think the very sensible one for a counter would be something that started before a counter that start with starts with zero then when an increased command comes in what I will do is I will create a new value that is the current state plus plus my incoming request so increase value by so so much then I have a new value and I tell now Klex what I want I want Klex to persist that update that state that's an integer or long I don't remember yeah an integer and here's the state I will just send a new state to Klex and Klex will persist it for me and then I confirm to my users that the command was accepted by send this empty message with kind of acknowledgement I will just copy this code here because it's almost the same except that this is the decreased one and I will do a subtraction and when the user sends a reset I will update the state back to zero the empty state and I reply and and finally the current state when I someone requires request the current state I will return this other type here which is then reply I will reply with demo current counter but the thing here is I have two options well first first option is to has the states the state that is persisted is the one that is getting returned here in pass to the to the method and it's counter state and the next one is the name and the name I can use in the command here in the incoming command there is the counter ID that's one option but this also available on the context is the entity ID I will use the entity ID is the identifier of this entity to fill in the name that I added here this one and the context is always available to your entity and the entity ID will be whatever we use to to call this counter not a view I create a new package here in the protobuf folder call it views and counter view photo and I will copy here some code that I already prepared and first some basic protobuf configuration import I would say then I want to import the types that I have already defined it here in my Klex demo project and I will define a service and if you remember the previous one here it was saying that to the we said to the code gen that's a value entity in this one we're gonna say to the code gen that's a view so first I'll start with this message here and then the updated methods the query methods let's let me start with the update method and I explain what it is so the updated method is saying there is a method that we receive counter state that is the state of my entity and we'll return current counter which is that representation that I have to that I want to expose to the external world then inside it I have Klex annotate say well I want to subscribe to any change that happened on entities identified by this entity type call it counter and then I want those updates to go to the counters table and now I'm gonna define the counters index or table which I do by create another method that receives a request and return a stream of count current counters and it will say give me everything in the counters index in the counters table whose value is greater or equal the value that I get from my request and you see here value it's repeated here so that this field here you need to match this one and that's what we get from the outside and is used it to execute the query when we generate our code we generate this main function and we have one counter here but now one component but now we have two components we have the counter and we have the view so what I will do I will delete this one and you let I will let Klex generate it generate it again I compile close this one this one as well and now I have the view and the view receives counter state and return current counter for the empty state in this view we are fine to just say no and for updates we just for every time that we get an update I will just up to return a new counter current counter effects update state and the first thing is the counter state is the value the second thing is the name but where I get the name here well the name I will get from the update context and the event subject here is the entity ID for the state that is being passed here inside and that's my view we have our view and now I want to deploy it in production so I will start SBT again but then now passing my Docker Hub username to it because I want to publish that image that project on my Docker Hub account to publish that Docker image into Klex normally you have to install the Klex clients I have already done it but for Mac you have a brief install for Linux and Windows there are the tooling you can have a look at all our documentation but let's say I have it already installed so the first thing that I do and I want to show you of course I already signed up but I want to show you that you can sign up from the command line yeah and you get this page where you can fill in or you can connect with Google I'm using here my Google account my my private one I just continue and and I don't have any project yet okay I sign up I think I still need to authenticate let's see yeah I want to continue it will ask me to give authorization to the command line to have access to my Klex project great now I will create a Klex project this one I will create a new Klex project Klex demo reactive submit and on this region you can choose the region I'm on Google Cloud and so far so good and let's see the image got published it's octonato Klex demo reactive submit and then I can call this command in Klex which will create a new service deploy something with this name Klex demo reactive submit and that's the image that we are looking for that it should look for to deploy okay Klex service lists yep unavailable and now my service is ready the next thing so I want to be able to call it from outside so I will ask Klex to expose this service and it will generate a URI for me just one and I will go back to my Joppy SQL and the port is 443 okay and everything that is written that is there is nothing there so that's it so what we saw here is we can develop an application with very minimal code just the basic just explaining to Klex what he wants for the views explaining to Klex what is the business logic and all the rest is being taken care by Klex that's basically the magic source of Klex is giving to you a knuckle cluster with doubts asking you to manage an knuckle cluster you just write your business logic now we can build a Klex application I want to go back to this slide here and what we saw it's a very simple application of course for demo we should keep it simple and small but imagine imagine that you have a very big system lots of counters and at some point you need to scale out you bring your code your code is just the counter and the view and they are deployed there but the state is managed by Klex and as I was saying we do that by using the knuckle cluster so now your application is a clustered application and stateful because the knuckle cluster take care of the state at any single time even if you have 20 nodes deployed there is only one instance of each single counter in memory doesn't matter where they will one instance over across the whole cluster so that we manage the state for you we managed stateful aka cluster application for you you want to bring your code and that's the magic source of Klex is that it's allowing now you everybody to build an application on top of aka cluster without even dealing with clustering database Kubernetes and everything you just bring in your code we do the rest okay before I wrap up a small announcement or teaser for a near future we have worked on the springers decay which is based on spring boots no protocol for encoding just Java you come write your code in Java you use jacos Jackson serialization and you can use the rest end points define the rest and points using spring annotations thank very much I love you to try out Klex the demo code it's on my github account at github.com octonato slash Klex demo reactive submit stay tuned for the upcoming springers decay that will be very it's really shaping very well I'm have very happy with what we are doing there and if you have questions I think we still have some time for questions I will be around otherwise you can contact me at renaughtatlightband.com and my Twitter account is just octonato like my github one thank very much