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 {
@SwimLane("mission")
CommandLane<String> mission = this.<String>commandLane()
.onCommand(mission -> System.out.println(nodeUri() + ": Mission: " + mission));
@Override
public void didStart() {
System.out.println(nodeUri() + ": Hello, agent!");
}
}
Breaking this down a bit:
-
We have created a command lane variable named
mission
, using theAbstractAgent
scommandLane()
method. -
The lane has a
String
parameter type, matching the type of payload it will receive. -
We add an
onCommand
callback that logs the payload received. This is not a compulsory and lanes can be created with no callbacks attached. -
We annotate the lane variable with
@SwimLane
, passing the lane URI ofmission
as an argument.
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
@Override
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.