 So, hello. So, my name is... I'm the first Sylvain, Sylvain Bobot. And yeah, we'll talk about graffiti. Graffiti was created because it's... First, we were working on Skydive, which is a networking tool. So, it's one of the features. It allows you to get the topology of your whole network infrastructure and to retrieve the topology and to visualize it. And so, the data model that we use for Skydive is a graph. And so, we extracted this part and we created a brand new project from this, which is graffiti. So, the engine is embedded inside Skydive. So, it's a graph engine which is highly event-based. So, everything in Skydive goes through events. It has interesting features. One of the interesting features we have is that it allows to time travel. So, it allows you to query the graph as it was at a certain point of time. It's highly available. So, you can have like multiple... We'll see later, but one of the components is the hubs. So, we can have multiple hubs. And so, it provides you high availability for your graph. And it also provides load balancing because we'll see that you can subscribe to multiple hubs. And so, to balance the load. So, why did we create our own engine? It's because, first, we were using existing graph engines. But we had the constraint of the embedding. So, that was our first constraint. But also, we wanted to be able to easily extend the query language that we were using. In fact, in Skydive, we implemented... In Gravity, we implemented our own Gremlin parser and executor. And so, we wanted to be able to add custom steps very easily and even steps that are not really graph related. So, that's the architecture of Gravity. The first component is the pod. So, the pod is a small agent. It has just a local graph, just part of the graph. That's where you create the nodes. So, in the case of Skydive, the pods are running on the machines of the infrastructure. And so, the graph is populated on the pod. And then the pod forwards its graph to another component, which is the hub. And the hub has the whole graph. So, it's in memory, but it's also persistent. So, you can also have a database behind it. So, as you can see, the hubs are replicated. They are connected, and the pods are connected to multiple hubs. Just in case of failover or load balancing. So, regarding the event mechanisms, it's a graph as a pub sub. So, internally, we need to use it in this embedded mode. You register callbacks on the graph, and then your code is triggered when any event happens on the graph. You can also subscribe to the graph externally through a web socket. So, that's the way the web UI works. And you can also publish to the graph. So, you can publish to a pod or to a hub. It doesn't make any difference. It's the same API. You can also subscribe just to a portion of the graph. If you are not interested in all the events of the graph, just a few nodes or subsets, you can subscribe on this. So, the events that you get are pretty straightforward. It's the node creation, the edge creation, the updates, the deletes. So, the messages are encoded in different formats. You can use JSON for the web UI, obviously. But you can also use Protobuf for performance reasons. So, that's the way the pods and the hubs are talking together, is through using Protobuf. So, regarding the history. So, we keep every modification on the graph. Generates a new revision of the elements. So, that allows us to do two things. It's just to say, show me the graph as it was at a specific point of time. But also to see all the modifications that happened on the node are subset of the graph. So, you can see, like, they give me what happened to this node and you will get all the events, all the modifications and the revisions of our node. So, to achieve this, so, to query, to use this time context, we introduced a new step, a gremlin step, which we called at. And you can see here that you can specify your time. So, let's say, this gremlin expression says the graph, how it was one minute ago. Or you can specify a date. And you can also say, give a time. And then the period where you want to get the revisions from. So, we support as a back end, we support elastic search. But we also support orientDB. But I would not recommend you to use this. Because all our efforts are put on the elastic search back end. We also have, like, in the case of elastic search, to maintain that the index are not too big. We have a rolling index mechanism. So, when you can set, like, I don't want my index to be more than a specific size or a specific number of nodes. So, to achieve high availability, we have a replication mechanisms between the hubs. And for the load balancing, the pods are used around robin connections to the hubs. We handle the reconnection. So, if the network connectivity goes down, then the pods will automatically reconnect and re-sync their graph with the hubs. And we have, and for the rolling index, this has to be done on a single hub. So, we have a master election. And for this, we use an ETCD. So, to write remnant extensions, they have to be written in Go, because graffiti is written entirely in Go. And your new step will be automatically available through the REST API. So, we did not implement all the gremlins specification, only the one we were really using. So, we have all the basic gremlins steps and the one we added specifically for the time selection. But we also added steps for networking purpose. So, in the case of Skydive, so the main user of graffiti, we added the flow steps so that when you can retrieve the network flows of your infrastructure, you can get some metrics. You can have, like, sockets. So, those are, I won't explain this because it's this network-specific stuff. But the fact is that it provides a graph transformation. So, if you do use the socket steps, then you have a new graph. And then you can also subscribe to this new graph and get the same feature that you have with the regular graph. And now, sorry, demo. Thank you. Okay, this is the first demo. So, just to introduce you to what it is. This is a web UI that we are using for Skydive, which is the core project for graffiti. But definitely it can be used by Skydive, sorry, but definitely you can use it with graffiti. So, that's what you can get. So, you can explore the graph. It's a kind of a tree because of Skydive. But then you have a regular graph. We can see we have multiple parents. And you can work through the graph. You will get metadata. Yes, sorry. And the metadata, you can have multiple metadata and you have a way to render them properly according to your needs. You have a way to do search, to select the column that you want to see. You can describe your metadata and the rendering used for that within a config file. So, since this is an embedded project, you embed your graffiti in your project and you provide metadata. And then the web UI will render it properly. And thanks to this story, for example, for the matrix, here it's for networking purpose. But then, thanks to this story, we can get a graph of the data requesting a period of time, something like this. And then, thanks to the web UI, we have a way to tag the links and the nodes. And then it will generate different views. So yeah, that's another view. So it's a Kubernetes infrastructure. So you can get the physical infrastructure and then the logical one. And basically, we have a kind of layer of graphs. And you can select the link types you want to see. And now, we are going to see that we are going to leverage the filtering subscribee mechanism. So yeah, when we click on this, the web UI is going to reconnect to the graffiti, subscribee to another subgraph and getting another view, meaning just a subgraph. So here, that's just the namespaces. And yeah, and you can do a quick search thanks to the web UI. There is a kind of index, and then it will open properly the node. And yeah. So just to summarize a bit, when to use graffiti and when to not use it. So definitely, if you want to write a go-long application, having an updated graph engine, you can use it. It's schema less or not. You can have schema, and that's useful sometime. If you want to have, like we did for Skydive, if you want to have a kind of grooming language, a common grooming language, but being able to extend it for specific purpose, you can definitely do this. If you want to have a distributed architecture, that's good too. And we do support hierarchy of graphs. So meaning if you want to have a subset of the infrastructure having a specific graph and then propagating the graph in a chain, that's possible. And attaching ACL, that's pretty useful because you can authorize some persona to do something or to subscribe to something. And to not use it, so definitely this is not good for any graph-specific algorithm in iComputing stuff. This is not the purpose of the project. It's definitely an embedded project. And if you have nodes or edges with a lot of metadata, binary attached to the metadata, that's not good too. Again, that's definitely an embedded project. For the way we are, it's definitely even based. I will show you that just after. You can do search, as I explained. Filtering, everything, you can put everything in a config file so you can really customize everything. That's one view you can get with, that's definitely a network. And first of all, you can see there is plenty of nodes. And I do have another demo. So basically the demo is about doing something which is completely outside of the scope of Skydive. So not networking purpose, that's really a demo. So it will be a Python demo, watching a directory, creating nodes for files or folders, creating edges for any kind of links between the entities. So basically the code is like this. We are watching, thanks to our notified folder. And we create nodes when we see a file or a folder. And then if it's a, we are linking the new file to the root node. And if it's a folder, we do this again. So that's fairly simple. This code is in Python. This code is in Python meaning that you do have this graffiti or Python binding. So you can, it's not mandatory to interact with graffiti with in-go line. And I'm going to show you that. It's going to be quick. So first we start the watcher. So it's going to watch a folder. Then I run the script. And we are rating a bit. So we have a host. And then if we expand it, we have our first folder which is watched. And then we start to demo the demo.sh which is going to create a few files. So, and just to show you that even base, we will see the web we are reacting on the events. And yes, few folders. And then finally, we will see a sim link between, between two files. Yeah, just here, that's a sim link. And yeah, you have a new link types that you can select if you want. And then the filtering again. Okay, I want to see only the folders and that's what, that's what I have. And I think that fits. So if you have, if there is any questions. If there are any questions, yeah. I have a question. How do you handle deletions or can you handle deletions because of the possibility of going back in time? Yeah, sorry, deletion. That's an event. That's part of the event stored. Let's repeat the question for the audience. Yes. How do we handle deletions of information nodes or edges, for example? Yeah. So basically we store this information within the data store. So that's, that's, that's one of the events we store. We store creation, deletion, updates. Maybe you want to, yeah. You mean in the data, how you restore it in the database or the way we, we mark a node as deleted? Yeah. Because every node has a lifetime basically as a created and delayed, delayed times. And then we just select the nodes that are still living at the time we query. And the store grows over time because at some point in time you have so much data. Yeah, that's what, yeah. Yeah, that's what we, we do have a rolling index stuff. Okay. Yeah. That's, that's one of the reason. And, but, and there is a revision which is kept, kept for all the modifications. So that's part of the mechanism. Yeah. Okay. So, so if you want to, if you use it as a, yes, is there any transaction, transaction thing? So if you use it internally, I mean, if you embed the project within your project, yes, we do have a mechanism for that. But if you interact it with the graffiti outside of the Golan scope, like in Python, there is nothing. So it's, but if you embed it as part of a Golan project, yes, there is a kind of mechanism for that. Yeah. Sorry. Can you repeat? Yeah. But you have to implement it yourself. Yeah. Thank you. Let's take a scan.