Command Service

Command Service provides a handle to send commands to a component which is registered in Location Service.

Creation of Command Service

Pre-requisite

In order to use command service for a specific component

  1. The component needs to be up and running behind the gateway server. GatewayException(InvalidComponent) will be thrown if the specified component is not found.
  2. Authorization Token with correct access role. Documentation on how to fetch authorization token could be found here.

For the given example : Prefix(ESW.Component1) needs to be registered in the Location Service as any of the component type (HCD, Assembly, etc.).

To create Command Service client for a component

Typescript
sourceconst tokenFactory = () => auth.token

const commandService: CommandService = await CommandService(new ComponentId(new Prefix('ESW', 'Component1'), 'HCD'), {
  tokenFactory
})

Type of Actions

Whenever a command gets submitted to a component, it results into in either Immediate completion or Long Running action.

Immediate completion

If the actions of the submit or submitAndWait command take a very short time to complete, it is referred as Immediate completion. The actions are successful, if the Completed SubmitResponse is returned. If there is a result, the Completed is returned with a parameter set of Result type that can be inspected by the caller.

Long running Actions

When actions take longer than 1 second the Component returns the Started SubmitResponse. The Started response indicates to the framework that long-running actions have been started.

Control Commands

In order to call the following method, one of the control command needs to be sent. Depending on your use case, you will be sending either Setup or Observe Command.

Following examples show how to create control commands:

Typescript
source// Definition of control command looks like following
type ControlCommand = Setup | Observe

// examples
const setupCommand: Setup = new Setup(new Prefix('ESW', 'Component1'), 'move-command', paramSet, 'obs-id')

const observeCommand: Observe = new Observe(new Prefix('ESW', 'Component1'), 'c1', paramSet, 'obs-id')
Async-Await

Note that the examples are using async/await which makes handling of promises more readable.

Usages of Command Service

Type definitions of all Command Service methods can be found here

Validating command

A validate message is used to ask a destination component to validate a command and determine if the command can be executed. It does not execute the command and only returns the result of validation. In some scenarios, it may be useful to test and see if a command can be executed prior to trying to execute the command.

Type definitions of validate method can be found here

Typescript
source
const validateResponse1: ValidateResponse = await commandService.validate(setupCommand) // or const validateResponse2: ValidateResponse = await commandService.validate(observeCommand)

Submitting commands

A submit message can be used when the sender of a command needs to do additional work before long-running actions are completed. For instance, send another command to execute in parallel. If commands are short, submit and submitAndWait behave the same way. When the actions started by submit are long-running, the caller can wait for the actions to complete if needed using the queryFinal call.

Type definitions of submit method can be found here

Typescript
sourceconst submitResponse1: SubmitResponse = await commandService.submit(setupCommand)
// or
const submitResponse2: SubmitResponse = await commandService.submit(observeCommand)

Submit And Wait for Response

This is a convenience method which sends a submit message and if the command is long-running, it waits for final completion. Sending submit message with a command returns a SubmitResponse as a Future.

Type definitions of submitAndWait method can be found here

Typescript
source// Submit a long running command and wait for the result for specific time

const submitAndWaitResponse: SubmitResponse = await commandService.submitAndWait(setupCommand, 10)

Submit Multiple commands and Wait

Similar to SubmitAndWait, submitAllAndWait method can be used to send multiple commands sequentially to the same component. This could be used to send initialization commands to an HCD, for instance.

Type definitions of submitAllAndWait method can be found here

Typescript
source// Submit multiple commands and wait for the result of each submitted command for specific time

const submitAllAndWaitResponse: SubmitResponse[] = await commandService.submitAllAndWait(
  [setupCommand, observeCommand],
  10
)

Sending Oneway Command

Oneway is useful when Command Service needs to send commands to an HCD as quickly as possible. The command gets validated on the destination and the validation response is returned, but no other responses are provided.

Type definitions of oneway method can be found here

Typescript
sourceconst onewayResponse1: OnewayResponse = await commandService.oneway(setupCommand)
// or
const onewayResponse2: OnewayResponse = await commandService.oneway(observeCommand)

Querying Result

This method is useful to get the result of a submitted command which returns a Started response if the command has triggered a long-running action, The caller can then determine that the actions have started properly, or wishes to poll the destination component for the final response using queryFinal method.

Type definitions of query method can be found here

Typescript
source// Submit a long running command
const res: SubmitResponse = await commandService.submit(setupCommand)
// .
// .
// .
// Get the current result of long running command as :
const queryResponse: SubmitResponse = await commandService.query(res.runId)

Querying for Final result

Similar to query, queryFinal uses the Id returned by Started. However, in this case rather than returning immediately like query, it waits and only returns when the final SubmitResponse is sent. The queryFinal method is useful exclusively with submit in the case where some other activity must be done before the actions started by the submit complete.

Type definitions of queryFinal method can be found here

Typescript
source// Submit a long running command
const result: SubmitResponse = await commandService.submit(setupCommand)
// .
// .
// .
// Get the final result of long running command within 10 seconds :
const queryFinalResponse: SubmitResponse = await commandService.queryFinal(result.runId, 10)

SubscribeCurrentState

This method can be used to subscribe to the CurrentState of a component by providing a callback that is called with the arrival of every CurrentState item.

Type definitions of subscribeCurrentState method can be found here

Typescript
source// subscribe to this set of current states
const currentStates = new Set(['stateName1', 'stateName2'])

// this callback gets called whenever the state changes
const onStateChangeCallback = (currentState: CurrentState) => {
  // do something when state changes
  console.log('changed state:', currentState)
}
//optional
const onErrorCallback = (error: ServiceError) => {
  // do something when error occurs
  // for ex : close connection / cleanup resources
  console.log(error)
}
//optional
const onCloseCallback = () => {
  // do something when connection is closed
  // for ex : reset client-side state
}
// subscribe call
const subscription: Subscription = await commandService.subscribeCurrentState(currentStates)(
  onStateChangeCallback,
  onErrorCallback,
  onCloseCallback
)

// .
// .
// .
// subscription can be cancelled when it is not required any more
subscription.cancel()