Server - Services

Swim developer logo developer.

Overview


Swim Services are distributed objects that are created on the server. A Service instance has the following features:

  • Stores state and data in Lanes.
  • Contains execution code defined in Lane callback functions.
  • Is thread-safe.
  • Has a persistent universal address expressed as a URI, for a Service, we call this the nodeUri.
Provided that Plane configuration has taken place, a Service instance is instantiated lazily when its nodeUri is invoked (i.e. via a command or a Downlink) for the first time. Unique Service instances are identified by the combination of dynamic components in the URI pattern specified in the Plane configuration.

Useful Functions


didStart

void didStart() is an overridable callback that will be invoked exactly once when any Service instance is initialized.

prop

Value prop(String property) can be invoked anywhere inside the Service class to receive the values of the dynamic components of the invoking instance's nodeUri, provided that property is included as a dynamic field in the Plane configuration.

Configuration


Configuring a Service class requires just a few steps.

  1. Extend swim.api.AbstractService.
  2. Optionally override didStart().
  3. Declare all Lanes and annotate them with @SwimRoute($laneUri), where each laneUri is a String that identifies the Lane for any instance of this Service.
  4. Ensure that Plane configuration has taken place.

Examples


This short example outlines all of the above points (Please refer to the swim-academy for comprehensive examples of Services). When the Plane runs, we will get the following behavior:

  1. Any requests, including those with invalid laneUris, that satisfy the nodeUri pattern /services/:id with id=foo will be routed by the Plane to a Service instance with URI /services/foo. If such an instance does not yet exist, the Plane will instantiate it.
  2. Upon its instantiation, each Service instance will set its myLane Lane, which is addressable by requests to (nodeUri=/services/foo, laneUri=myInfo), to foo.
// src/main/java/ai/swim/MyPlane.java package ai.swim; import swim.api.*; public class MyPlane extends AbstractPlane { @SwimRoute("/services/:id") final ServiceType myService = serviceClass(ai.swim.service.MyService.class); } // src/main/java/ai/swim/service/MyService.java package ai.swim.service; import swim.api.*; public class MyService extends AbstractService { @SwimLane("myInfo") // NOTE: annotation does not need to match field name private ValueLane myLane = valueLane().didSet((n,o) -> System.out.println("myInfo set with: " + n.toRecon())); @Override public void didStart() { // id must be specified as a dynamic property for this ServiceType in the Plane myLane.set(prop("id")); } }
  • HTML
  • recon