Getting Started
This is a brief tutorial that will help guide you through high-level Vertigo concepts and go through a simple network example. Check out the repository for more examples.
Setup
Vertigo can be added to your project as a Maven dependency or included in your modules via the Vert.x module system.
Adding Vertigo as a Maven dependency
<dependency>
<groupId>net.kuujo</groupId>
<artifactId>vertigo</artifactId>
<version>0.7.0-beta2</version>
</dependency>
Including Vertigo in a Vert.x module
To use the Vertigo Java API, you can include the Vertigo module in your module’s
mod.json
file. This will make Vertigo classes available within your module.
{
"main": "com.mycompany.myproject.MyVerticle",
"includes": "net.kuujo~vertigo~0.7.0-beta2"
}
Networks
Networks are collections of Vert.x verticles and modules that are connected together by input and output ports. Each component in a network contains processing logic, and connections between components indicate how messages should be passed between them. Networks can be created either in code or in JSON and can be deployed in code or from the command line.
Components
As with any Vert.x verticle, Vertigo components can be deployed with any number of instances. Components communicate with each other over the Vert.x event bus. But Vertigo doesn’t use raw event bus addresses. Instead, components communicate through named output and input ports. This allows components to be abstracted from the relationships between them, making them reusable.
Messaging in Vertigo is inherently uni-directional. Components receive messages from other components on input ports and send messages to other components on output ports.
Messages are not routed through any central router. Rather, components communicate with each other directly over the event bus.
public class MyComponent extends ComponentVerticle {
@Override
public void start() {
input.port("in").messageHandler(new Handler<String>() {
public void handle(String message) {
output.port("out").send(message);
}
});
}
}
public class MyComponent extends ComponentVerticle {
@Override
public void start() {
input.port("in").messageHandler((message) -> output.port("out").send(message));
}
}
TODO
TODO
Ports do not have to be explicitly declared. Vertigo will lazily create ports if they don’t already exist. Messages can be of any type that is supported by the Vert.x event bus. Vertigo guarantees that messages will always arrive in the order in which they were sent.
In cases where a connection connects two components with multiple instances, Vertigo facilitates special routing between the components with selectors.
While components receive messages on input ports and send messages to output ports, the network configuration is used to define how ports on different components relate to one another. Connections between components/ports in your network indicate how messages will flow through the network.
NetworkConfig network = vertigo.createNetwork("foo");
network.addComponent("bar", "bar.js", 2);
network.addComponent("baz", "baz.py", 4);
network.createConnection("bar", "out", "baz", "in");
TODO
TODO
The Vertigo Cluster
Vertigo provides its own cluster abstraction within the Vert.x cluster. Vertigo clusters are simple collections of verticles that manage deployment of networks, allow modules and verticles to be deploy remotely (over the event bus) and provide cluster-wide shared data structures. Clusters can be run either in a single Vert.x instance (for testing) or across a Vert.x cluster.
Rather than communicating over the unreliable event bus, Vertigo uses Hazelcast data structures to coordinate between the cluster and components. This is one of the properties that makes Vertigo networks fault-tolerant. Even if a failure occurs, the network configuration will remain in the cluster and Vertigo will automatically failover any failed components.
A Simple Network
Vertigo provides all its API functionality through a single Vertigo
object.
Vertigo vertigo = new Vertigo(this);
TODO
TODO
The Vertigo
object supports creating and deploying networks. Each language
binding has an equivalent API.
NetworkConfig network = vertigo.createNetwork("word-count");
network.addComponent("word-feeder", RandomWordCounter.class.getName());
network.addComponent("word-counter", WordCounter.class.getName(), 2);
network.createConnection("word-feeder", "word", "word-counter", "word", new HashSelector());
TODO
TODO
Vertigo components can be implemented in a variety of languages since they’re
just Vert.x verticles. This network contains two components. The first component
is a Python component that will feed random words to its word
out port. The second
component is a Javascript component that will count words received on its word
in
port. The network therefore defines a connection between the word-feeder
component’s
word
out port and the word-counter
component’s word
in port.
Note that since we defined two instances of the word-counter
component, it’s
important that the same words always go to the same instance, so we use a
HashSelector
on the connection to ensure the same word always goes to the
same component instance.
random_word_feeder.py
TODO
import vertx
from vertigo import component, input
@component.start_handler
def start_handler(error=None):
if not error:
words = ['apple', 'banana', 'pear']
def feed_random_word(timer_id):
output.send('word', words[rand(len(words)-1)])
vertx.set_periodic(1000, feed_random_word)
TODO
Here we simply send a random word to the word
out port every second.
word_counter.js
TODO
var input = require('vertigo/input');
var output = require('vertigo/output');
var words = {};
input.port('word').messageHandler(function(word) {
if (words[word] === undefined) {
words[word] = 0;
}
words[word]++;
output.port('count').send({word: word, count: words[word]});
});
TODO
This component registers a message handler on the word
in port, updates
an internal count for the word, and sends the updated word count on the
count
out port.
In order for a network to be deployed, one or more nodes of a Vertigo cluster
must be running in the Vert.x cluster. Vertigo clusters are made up of simple
Vert.x verticles. To deploy a cluster node deploy the vertigo-cluster
module.
vertx runmod net.kuujo~vertigo-cluster~0.7.0-beta2 -conf cluster.json
The cluster configuration requires a cluster
name.
{
"cluster": "test-cluster"
}
A test cluster can also be deployed locally through the Vertigo
API.
vertigo.deployCluster("test-cluster", new Handler<AsyncResult<ClusterManager>>() {
public void handle(AsyncResult<ClusterManager> result) {
ClusterManager cluster = result.result();
}
});
vertigo.deployCluster("test-cluster", (result) -> {
ClusterManager cluster = result.result();
});
TODO
TODO
Once the cluster has been deployed we can deploy a network to the cluster.
cluster.deployNetwork(network);
TODO
TODO
Vertigo also supports deploying networks from the command line using simple JSON configuration files. See deploying a network from the command line.