Project Iris

Completely decentralized cloud messaging

Zero configuration, self organization and semantic addressing.
Perfect secrecy against passive and active attacks.
Beautiful, simple and language agnostic API.

Want to learn more? The book of Iris!

Version v0.3.0... shiny, stable APIs!

Published: Aug 11, 2014

Iris made its first public preview appearance almost a year ago, at the time being little more than a research project. It was built around the concept of self-organizing, zero-configuration and language-independent micro-services. The goal was to bring the simplicity and elegance of cloud computing to the application layer. Although many were enthusiastic about it, at that point Iris was merely in a prototype phase.

Fast forward one year, and I'm happy to announce the release of version v0.3.0 of Iris. Beside the various bugfixes and performance improvements, the highlight of the release is the huge effort placed behind stabilizing the client APIs and the network protocol between them and Iris itself. The goal of the release was to mature these to such a level, as to allow tagging them as stable.

Clients and services separated

Iris originally considered service entities (processes that receive inbound messages) as the only possible agent types within a distributed system, they themselves being able to act as clients to other nodes. Although this abstraction is valid, it led to confusion in the rare case where a network entity really does want to be only a client. To fix this issue once and for all, user processes may from now on attach to Iris as plain clients too (Erlang vs. Go):


main() ->
  % Start an iris_client, connecting to the local relay on
  % port 55555. A client cannot accept inbound requests,
  % broadcasts and tunnels, only initiate them.
  {ok, Client} = iris_client:start(55555),

  % Disconnect from the Iris network
  ok = iris_client:stop(Client).
package goclient
import ""

func main() {
  // Connect to the local relay on port 55555 as a client.
  // A client cannot accept inbound requests, broadcasts
  // and tunnels, only initiate them.
  conn, err := iris.Connect(55555)
  if err != nil {
  // Ensure the connection is torn down
  defer conn.Close()

Service connections are of course still supported, but have been omitted to keep the announcement short and sweet. For details and code snippets, please check the Book of Iris: Run, Forrest, Run chapter's connection section on the bottom right.

Resource capping

Up until this point, connecting services had no way of limiting the resources consumption of inbound messages. This lead to the possibility of overloading a service by sending it too many concurrent requests: it either crawled to a halt (CPU exhaustion) or even crashed (memory exhaustion). To prevent such scenarios, user configurable service limits were put into place, tunable during service registration (defaults used if unset):


main() ->
  % Create the resource limits for the service events. The values
  % below are the default ones.
  Limits = [
    {broadcast_memory, 64 * 1024 * 1024},
    {request_memoty,   64 * 1024 * 1024}
  % Start an iris_server with the service limits set
  iris_server:start(55555, "cluster", callback, args, Limits).
package golimited
import ""

func main() {
  // Create the resource limits for the service events. The val-
  // ues below are the default ones.
  Limits := iris.ServiceLimits{
    BroadcastThreads: 4 * runtime.NumCPU(),
    BroadcastMemory:  64 * 1024 * 1024,
    RequestThreads:   4 * runtime.NumCPU(),
    RequestMemory:    64 * 1024 * 1024,
  // Register an Iris service with the limits set
  iris.Register(55555, "cluster", new(callback), Limits)

Similar limits may be set on topic subscriptions too, but as they are completely analogous, they have been omitted. Note, that the Erlang binding has no possibility to put limits on the concurrency due to its functional nature (events arrive on a single thread, the user being responsible for spawning workers if needed (same as gen_server)).

Contextual logging

The last feature highlight of the release is the introduction of contextual loggers into the bindings. Every communication entity in the system (client connection, service connection, topic subscription and tunnel) has its own logger, through which ID tagged messages may be logged. The details for accessing and using these is language dependent (Erlang vs Go), but a short sample snippet can be found below:

{ok, Client} = iris_client:start(55555),

Logger = iris_client:logger(Client),
iris_logger:debug(Logger, "debug entry, hidden by default"),
iris_logger:info(Logger, "info entry, client context included"),
iris_logger:warn(Logger, "warning entry", [{extra, "some value"}]),
iris_logger:crit(Logger, "critical entry", [{bool, false}, {int, 1}]),

ok = iris_client:stop(Client).
conn, _ := iris.Connect(55555)
defer conn.Close()

conn.Log.Debug("debug entry, hidden by default")
conn.Log.Info("info entry, client context included")
conn.Log.Warn("warning entry", "extra", "some value")
conn.Log.Crit("critical entry", "bool", false, "int", 1)

The output (slight variations based on language of choice) for the code snippets above is:

19:17:31.985 [info] connecting new client                    client=1 relay_port=55555
19:17:31.999 [info] client connection established            client=1
19:17:32.000 [info] info entry, client context included      client=1
19:17:32.000 [warning] warning entry                         client=1 extra="some value"
19:17:32.000 [critical] critical entry                       client=1 bool=false int=1
19:17:32.000 [info] detaching from relay                     client=1

As you can see, beside the custom user logs, various life-cycle events are also entered into the logger. These can be restricted by raising the log level above INFO, or can be extended to logging every network event by lowering it to DEBUG.

Goodies... just for You!

Last but not least, a small collection of fresh goodies to keep you occupied a while ;)

Like what yo see? Head over to the downloads section and go wild! :D

Still looking for support

As of the current release, my focus will shift back to finalizing my dissertation and inherently, my PhD. Since I can no longer rely on university support for Iris, I am actively looking for an official backer who would be interested in taking Iris to the next level and turning it into an industrial strength project. If you are interested, or know of such a person, please contact me at