2.5. Hello, Lane!

Now that we’ve established several agents, the next step is to expose their state and provide a method for interacting with them. This is where lanes come into play. Lanes will be thoroughly covered in a dedicated chapter. To help you start using lanes, we’ll bypass certain details until that chapter.

Opening a Lane

Let’s add the most basic form of a lane - a command lane - to the Agent class we had before.

File: src/main/java/tutorial/Agent.java

import swim.api.SwimLane;
import swim.api.agent.AbstractAgent;
import swim.api.lane.CommandLane;

public class Agent extends AbstractAgent {

  CommandLane<String> mission = this.<String>commandLane()
      .onCommand(mission -> System.out.println(nodeUri() + ": Mission: " + mission));

  public void didStart() {
    System.out.println(nodeUri() + ": Hello, agent!");


Breaking this down a bit:

This has essentially created a method on the agent that can be called from anywhere. Going back to the didStart method of our MainPlane, we can modify our commands to test this lane.

File: src/main/java/tutorial/MainPlane.java

  public void didStart() {
    System.out.println("Hello, world!");
    command("/Bond", "mission", Text.from("Protect and serve"));
    command("/Holmes", "mission", Text.from("Crack the case"));

Notice that the middle argument we left blank before is now occupied with the URI of the lane we just created.

The third and final argument of the command is the payload. This topic will be explored in greater detail in a subsequent chapter. However, for now, it’s important to understand that in order for SwimOS to transmit payloads, they must be serializable to Recon. This is why we convert the strings to Text objects.

Let’s give this a run:

$ ./gradlew run

> Task :run
Starting server...
Hello, world!
Running server...
/Bond: Hello, agent!
/Holmes: Hello, agent!
/Holmes: Mission: Crack the case
/Bond: Mission: Protect and serve
<=========----> 75% EXECUTING [1s]

We can see a few things happening here as a result of us commanding the lane. Initially, as observed previously, the agent didn’t exist, prompting the initiation of a new one and triggering the didStart callback. Subsequently, the onCommand callback on the mission lane is invoked, passing along the payload we provided.

This is a great start to building streaming applications - agents and lanes are the core of SwimOS. In the upcoming chapters, we’ll circle back to cover certain details we skipped over and introduce you to new features of agents and lanes.