Developer Guide
Ravel Overview
Ravel allows multiple applications to execute simultaneously and collectively drive network control. This is accomplished through orchestration. A Ravel user sets priorities on the orchestrated applications using the ordering passed to the orch load
command. (For more details, see the orchestration demo in the Walkthrough.)
Applications can propose updates (through an insertion, deletion, or update to one of its views), which are then checked against the policies of all other orchestrated applications. If the proposed update violates the constraints of another application, a higher priority application can overwrite the update.
Ravel Base Tables
Ravel uses a flat representation of the network and exposes the topology and forwarding tables as SQL tables. Tables that may be of interest to applications are:
Additional node tables include:
Developing Applications
Applications in Ravel can consist of two components: an implementation in SQL and a sub-shell implemented in Python. Application sub-shells provide commands to monitor and control the application from the Ravel CLI. Name the SQL file [appname].sql and the Python file [appname].py, and place both files in the apps/ directory. The CLI will search for SQL and Python files in this directory.
For an overview of the CLI and application superclasses, see the API.
SQL Component
An application’s SQL component can create tables, views on Ravel base tables,
or add triggers on Ravel base tables. To interact with orchestration, an application must define its constraints and a protocol for reconciling conflicts. To add constraints, create a violation table in the form appname_violation
. To create a repair protocol, add a rule in the form appname_repair
.
For example, suppose we want to implement a bandwidth monitor that limits flows to a particular rate (see apps/merlin.sql for the full implementation). We can create a table to store the rate for each flow:
And then a violation table that finds flows that violate the constraint fid < rate
:
If the view contains more than zero rows, a conflict has occurred. To repair a conflict, we can reset the flow rate:
Python Sub-Shell
To interact with an application, the Ravel CLI can load a shell with commands for monitoring and controlling the application’s behavior. An application sub-shell can be launched from the Ravel CLI by typing the application’s name or shortcut after it has been loaded. To create a sub-shell, create a Python file with a class extending AppConsole and add the following variables:
shortcut
: defines a shortcut for the application from the Ravel CLIdescription
: a short description of the applicationconsole
: defines the class inheriting AppConsole
For example:
The AppConsole class contains the properties:
self.db
: a reference to ravel.db.RavelDbself.env
: a reference to ravel.env.Environment, the CLI’s executing environmentself.components
: a list of ravel.app.AppComponent, the application’s SQL components (i.e., tables, views, rules)
For more information about the application superclasses and their properties, see the API.
Measuring Performance
The Ravel CLI provides the command time
to measure the execution time of a command, similar to the Linux time command: time [command] [command args]
.
For more granular inspection of performance, the Ravel CLI provides a profile
command. This command reports the execution time of manually-defined blocks of code. When extending the Ravel runtime or developing applications, a new block of code can be defined using the class profiling.PerfCounter. The constructor accepts a string to identify the block of code. The functions start() and stop() define the start and end of the code to be profile: