skitter logo

Skitter

Skitter is a component agnostic, reactive workflow system.

Skitter makes it possible to wrap arbitrary data processing applications into reactive components. These components can be combined into reactive workflows, which can process data entering the system from the outside world.

Status

We are currently working on a new version of skitter, which aims to improve the expressivity of the language while also making it easier to use Skitter on a cluster. This release is the last effect based version of Skitter. The instructions in the "Getting started" section below only apply to this release.

If you are interested in the most recent version of Skitter, please look at the current status on GitHub.

Getting started

Information to get started with Skitter is provided below, some familiarity with elixir and its tooling (mix, iex) is assumed.

Documentation for this version of Skitter can be found here.

Installation

In order to use Skitter, you need to install elixir. Please ensure you use elixir version 1.8 or above.

Afterwards, clone the current version of the repository and fetch and build its dependencies:

$ git clone --depth 1 --branch v0.1.1 https://github.com/mathsaey/skitter.git
$ cd skitter
$ mix deps.get
$ mix deps.compile

Local use

You can use the elixir shell to play around with skitter in local (i.e. non-distributed) mode:

$ iex -S mix

In the shell, you can define components and workflows:

iex(1)> import Skitter.Component

iex(2)> component FahrenheitToCelcius, in: fahrenheit, out: celcius do
...(2)>   react fahrenheit do
...(2)>     ((fahrenheit - 32) * (5 / 9)) ~> celcius
...(2)>   end
...(2)> end

iex(3)> component Printer, in: data do
...(3)>   effect external_effect
...(3)>
...(3)>   react data do
...(3)>     IO.inspect(data)
...(3)>   end
...(3)> end

iex(4)> import Skitter.Workflow

iex(5)> workflow Example, in: fahrenheit do
...(5)>   converter = instance FahrenheitToCelcius
...(5)>   printer = instance Printer
...(5)>
...(5)>   fahrenheit ~> converter.fahrenheit
...(5)>   converter.celcius ~> printer.data
...(5)> end

Once defined, you can load the workflow and send it some data:

iex(6)> {:ok, instance} = Skitter.Runtime.load_workflow(Example)

iex(7)> Skitter.Runtime.react(instance, fahrenheit: 4)

Please look at the documentation for more information.

Distributed use

To run a distributed Skitter application, the component and workflow code should be packaged in a mix project which is present on the worker and master nodes. A small project with some example code to help you get started can be found here.

After unzipping the project, navigate to the project and fetch the dependencies:

$ cd skitter_0.1.1_example
$ mix deps.get
$ mix deps.compile

We can use iex -S mix to verify everything works in local mode:

$ iex -S mix

iex(1)> SkitterExample.load_and_react()

If everything works in local mode, we can try to execute Skitter in distributed mode on our local machine. To do so, start two terminals and navigate to the example project directory.

In one terminal, start a worker node:

$ mix skitter.worker

Start a master node in the other terminal. When starting a master node, pass along the name of the worker node (worker@<your-hostname-here>) and a command to evaluate (Skitter.Example.load_and_react() in our case):

$ mix skitter.master worker@hostname --eval "SkitterExample.load_and_react()"

If everything is set up correctly, converted temperatures should be visible in the worker terminal.

Once everything is set up, you can define your own components, workflows and data delivery code based on the code in lib/.

To execute code on a cluster, ensure every node has a copy of the mix project you are executing. Afterwards, run mix skitter.worker on every worker node. Finally, start the master node with the names of the worker nodes ( mix skitter.master worker@worker1-hostname worker@worker2=hostname … --eval "SkitterExample.load_and_react()" ).