Agent Relationship
Nstream provides ‘Group’ and ‘Member’ patches that greatly facilitate grouping agents by some common property. This guide demonstrates how to group agents and maintain a join lane downlinking it’s members.
Dependencies
Gradle
implementation 'io.nstream:nstream-adapter-common:4.15.23'
Maven
<dependency>
<groupId>io.nstream</groupId>
<artifactId>nstream-adapter-common</artifactId>
<version>4.15.23</version>
<type>module</type> <!-- Remove or comment this line for non-modular projects -->
</dependency>
Config
Most cases of grouping agents can be implemented using config only in the server.recon.
This involves adding MemberPatch and GroupPatch to the relevant nodes and setting some simple parameters.
Group Patch
The GroupPatch agent contains a JoinValueLane named agents that will downlink the specified lane of its members.
Simply define a node that includes the GroupPatch agent:
# server.recon
...
space: @fabric {
@plane(class:"nstream.adapter.runtime.AppPlane")
# Domain Agents
# 'Country' group agent that will be used to group 'sites'
@node {
pattern: "/country/:country"
@agent(class: "nstream.adapter.common.patches.GroupPatch")
}
}
Member Patch
The MemberPatch agent provides functionality to join and leave group agents (GroupPatchs).
Static Groupings
The group a member belongs to will sometimes be constant throughout the lifecycle of the server - for example a stationary site will always be a member of the region/state/country.
In this case, we can provide a static groupUri in the config of the MemberPatch.
# server.recon
...
# Domain Agents
@node {
uri: "/country/:country"
@agent(class: "nstream.adapter.common.patches.GroupPatch")
}
@node {
pattern: "/site/:id"
@agent(class: "nstream.adapter.common.patches.LatestValuePatch")
@agent(class: "nstream.adapter.common.patches.MemberPatch") {
groupUri: "/country/US" # Static node URI of the group to join
}
}
Dynamic Groupings
Some members will leave and join groups depending on some changing value or state. For this case, we define two properties:
-
extractGroup: a value selector to extract the group from an event. -
groupUriPattern: URI pattern of the group, which should match the URI pattern of the group patch in theserver.recon.
# server.recon
...
# Domain Agents
@node {
uri: "/country/:country"
@agent(class: "nstream.adapter.common.patches.GroupPatch")
}
@node {
pattern: "/site/:id"
@agent(class: "nstream.adapter.common.patches.LatestValuePatch")
@agent(class: "nstream.adapter.common.patches.MemberPatch") {
groupUriPattern: "/country/:country" # URI pattern of the group
extractGroup: $country # Selector to extract the 'country' from an event
}
}
Member Patch Config Options
| Name | Description | Required | Default | Example |
|---|---|---|---|---|
memberLane |
Lane the group’s join lane will downlink | true | latest |
status |
groupUri |
Node URI of group node | required if not using groupUriPattern
|
/country/US |
|
groupUriPattern |
URI pattern of group nodes | required if not using groupUri
|
/country/:country |
|
extractGroup |
Value selector of group from event | required when using groupUriPattern
|
$country |
Common Variations
Complex Group URIs
If the node URI of the group is more complex than applying a single value to a URI pattern then it may be necessary to override and add some custom logic.
// ZoneMemberAgent.java
// import ...
public class ZoneMemberAgent extends MemberPatch {
@Override
protected Uri getGroupUriFromEvent(final Value event) {
return
groupUriPattern() // From agent properties '/country/:country/zone/:zone'
.apply(
event.get("country").stringValue(),
event.get("zone").stringValue()
);
}
}
Remember to update the server.recon to use the new agent just created (instead of the base MemberPatch).
Nstream is licensed under the Redis Source Available License 2.0 (RSALv2).