DSS Service Components

Glossary Item Box

Microsoft Robotics Developer Studio Send feedback on this topic

DSS Service Components

Services is the basic building block for writing applications using Distributed Software Services (DSS), and is a key component of the DSS application model. A good place to look at services in action is the Service Tutorials Overview which demonstrates many of the concepts described here. Services can be used to represent anything including, but not limited to:

  1. Hardware components such as sensors and actuators

  2. Software components such as User Interface (UI), storage, directory services, etc.

  3. Aggregations: Sensor fusion, mash-ups, etc.

Services are executed within the context of a DSS node. A DSS node is a hosting environment that provides support for services to be created and managed until they are deleted or the DSS node is stopped. Services are inherently network enabled and can communicate with each other in a uniform manner. This works regardless of whether they are executed within the same DSS node or across the network.

The DSS service model has been designed to facilitate reuse of services. It does this by making them easy to use and compose with each other while enforcing a very loose coupling between them. All DSS services consist of a common set of components as described in this section.

Illustration of components of a DSS service.

Service Identifier

When a service instance is created within a DSS Node, it is dynamically assigned a Universal Resource Identifier  (URI), by the constructor service. This service identifier refers to a specific instance of a service identifier running on a particular DSS node. The service identifier is what enables other services to communicate with that service as well as Accessing DSS Services through a Web Browser. The service identifier only provides identity of a service instance; it does not convey information about the service state, behavior, or context. It is never safe to guess about what a service is based on the service identifier.

The service identifier is determined by the following steps:

  1. If a service instance name is indicated in DSS Service Manifests, then that name is used

  2. If a service instance name is indicated in a Create request sent directly to the DSS System Services, then that name is used

  3. If a service implementation has a ServicePort attribute looking like this,

    [ServicePort("/mysample")]
    

    then the name is the host and port name of the DSS Node with "/mysample" appended. For example:

    http://machine:port/mysample
    
  4. If a service implementation has a ServicePort attribute with a AllowMultipleInstances = true like this,

    [ServicePort("/mysample", AllowMultipleInstances = true)]
    

    then the name of the service instance is the same as above but with a Globally Unique Identifier (GUID), appended to further differentiate this instance from other instances. For example:

    http://machine:port/mysample/d88441c9-8319-407c-b554-0b0bfd90050b
    

Contract Identifier

A contract is a condensed description of a service implementation that describes its behavior. This is done so other services can compose and reuse services with a given contract. The contract of a service can be inspected using the DSS Contract Information Tool (DssInfo.exe). Contracts are used to generate DSS proxy Dynamic Link Library (DLL) links. This is what services link against when talking to other services, rather than linking directly with each other.

A contract identifier is a URI that uniquely identifies the contract of a service. A contract identifier is automatically created when creating a service project, for example using the DSS New Service Generation Tool (DssNewService.exe).

 

http://schemas.tempuri.org/[year]/[month]/[name].html

Service State

The service state is a representation of a service at any given point in time. One way to think of the service state is as a document that describes the current content of a service. Examples of state documents include:

  1. The state of a service representing a motor may consist of rotations per minute, temperature, oil pressure, and fuel consumption.
  2. A service representing a work queue may contain a list of all queued work items and their current status. The work items themselves may be services allowing the work queue to simply refer to them using their identity.
  3. A service representing a keyboard may contain information about which keys have been pressed.

Any information that is to be retrieved, modified, or monitored as part of a DSS service must be expressed as part of the service state.

In addition to capturing the current share of a service, the state also can be used to drive the UI of a service, see Accessing DSS Services through a Web Browser.

Service Partners

A critical part of the DSS application model is to enable services to compose with each other providing higher level functions. This means for services to effectively take advantage of each other, they must be able to discover and establish communication with each other in an efficient and predictable manner. However, as services are loosely coupled, a service does not know apriori whether other services that it depends on are available. It also doe not know, where these other services are placed. To address this issue, the DSS application model provides the notion of partner services.

Partner services, are other services that a service interacts with and possibly depends on in order to function properly. By declaring a set of other services as partners, a service can indicate to the runtime that it wants to be wired up with these services as part of the creating the service itself. A partner is declared using the partner attribute which has a rich set of options controlling exactly what the partner relationship is with each of the declared partners. For example, a service can declare that a partner is required in order for the service to run and if that partner can not be found then there is no need for the service to start. Partners can also be declared as being optional, in which case the runtime attempts to wire up the service with the partner. Then if it doesn't succeed the creation process continues regardless. 

Main Port

The main port is a CCR port where messages from other services arrive. It is also known as the operations port. Because service implementations do not link against each other directly, a service can only talk to another service by sending a message to its main port. The main port itself is a private member of the service class and is identified by the ServicePort attribute. An example of a main port declaration is:

[ServicePort("/mysample")]
private MySampleOperations _mainPort = new MySampleOperations();

The messages accepted on the main port are defined by the type of the port, in the case above by the type MySampleOperations. All operations defined on the main port must either follow the message operations defined by Decentralized Software Service Protocol (DSSP) or by HTTP (see Accessing DSS Services through a Web Browser). An example of a main port definition that supports the DSSP operations LOOKUP, DROP, GET, and REPLACE, as well as the HTTP operations GET and POST is:

    public class MySampleOperations : PortSet<DsspDefaultLookup, DsspDefaultDrop, Get, Replace, HttpGet, HttpPost>
    {
    }

Service Handlers

For each of the DSSP operations defined on the main port, service handlers need to be registered to handle incoming messages arriving on that port. The only exception is the handling of the operations DsspDefaultLookup and DsspDefaultDrop for which the DSS runtime registered default handlers. For example, in the case of the MySampleOperations definition above, the MySample service would register handlers for Get, Replace, HttpGet, and HttpPost, see also Accessing DSS Services through a Web Browser.

Service handlers can be registered declaratively using the ServiceHandler attribute. See Service Tutorials Overview for further details. This example registers a service handler for the DSSP GET operation:

[ServiceHandler]
public IEnumerator<ITask> GetHandler(Get get)
{
    get.ResponsePort.Post(_state);
    yield break;
}

Within the context of a service handler, a service can send messages to other services. There are two ways a service can send messages:

  1. Unsolicited, in the form of a request message sent to another service

  2. Solicited, in the form of an event notification sent to a subscriber as a result of a state change within the service generating the event notification

In either case, messages are sent through a service forwarder which is a local Concurrency and Coordination Runtime Port (CCR Port). representing the main port of the remote service. When a message is sent through the service forwarder, it gets forwarded down through the runtime until it reaches a transport. This transport will route the message, possibly through the network, to the transport of the other service. Here the message will get forwarded back up through the runtime until it reaches the main port of the receiving service.

 

Bb483067.ForwarderChain(en-us,MSDN.10).png

Event Notifications

A common pattern used in DSS services is that of subscribing to other services. A service generates event notifications as a result of changes to its own state. For each subscription a service has established with other services, the service will receive event notifications on separate CCR ports. By using different ports for each subscription, it is possible to differentiate event notifications and determine which subscription each event notification is associated with. Further, because event notifications arrive on ports, it is possible to orchestrate event notification messages using the full spectrum of CCR primitives.

Because event notifications are generated as a result of changes to the state of a service, and state changes happen as a result of DSSP operations such as DELETE, INSERT, UPDATE, etc. The actual event notification messages are exactly the set of operations on the main port that affect state change. As a result, a local notification port where event notifications arrive is of the same type as the main port of the service associated with that particular subscription. For example, if we introduce a service called MySample2 and MySample subscribes to that service. The type of the local notification port in MySample service where notifications arrive as a result of state changes in the MySample2 service is the same as that of the MySample2 main port.

 

 

© 2012 Microsoft Corporation. All Rights Reserved.