Managing Command State
A component has access to commandResponseManager
which is used to manage the state of commands during its execution. On receiving a command as a part of onSubmit
, the component framework adds the command to an internal CommandResponseManager. The component should then update the status of the command using the following API provided in commandResponseManager
:
addOrUpdateCommand
Add a new command or update the status of an existing command.
- Scala
-
// after validation of the controlCommand, update its status of successful validation as Accepted // TODO -- This isn't needed, but it must be part of docs // commandResponseManager.addOrUpdateCommand(controlCommand.runId, Started(controlCommand.runId))
- Java
-
// after validation of the controlCommand, update its status of successful validation as Accepted CommandResponse.Accepted accepted = new CommandResponse.Accepted(controlCommand.runId()); // TODO - REALLY? //commandResponseManager.addOrUpdateCommand(controlCommand.runId(), accepted);
addSubCommand
A received command can be often split into two or more sub-commands. The status of original command can then be derived from the status of the sub-commands. In order to achieve this, a component has to first add the sub-commands against in relation to the parent command using this method.
- Scala
-
shortSetup = Setup(prefix, shortRunning, controlCommand.maybeObsId) commandResponseManager.addSubCommand(runId, shortSetup.runId)
- Java
-
Prefix prefix = new Prefix("wfos.red.detector"); Setup subCommand = new Setup(prefix, new CommandName("sub-command-1"), sc.jMaybeObsId()); commandResponseManager.addSubCommand(sc.runId(), subCommand.runId()); Setup subCommand2 = new Setup(prefix, new CommandName("sub-command-2"), sc.jMaybeObsId()); commandResponseManager.addSubCommand(sc.runId(), subCommand2.runId());
updateSubCommand
Update the CommandResponse
of the sub-command which would trigger the automatic derivation of the status of the original/parent command when status of all the sub-commands have been updated. A CommandResponse
indicating failure such as Invalid
or Error
in any one of the sub-commands would result in the error status of the parent command. Status of any other sub-commands wil not be considered in this case.
- Scala
-
// An original command is split into sub-commands and sent to a component. The result of the command is // obtained by subscribing to the component with the sub command id. case _: Completed ⇒ controlCommand.runId match { case id if id == shortSetup.runId ⇒ currentStatePublisher .publish(CurrentState(shortSetup.source, StateName("testStateName"), Set(choiceKey.set(shortCmdCompleted)))) // As the commands get completed, the results are updated in the commandResponseManager commandResponseManager.updateSubCommand(id, Completed(id)) case id if id == mediumSetup.runId ⇒ currentStatePublisher .publish(CurrentState(mediumSetup.source, StateName("testStateName"), Set(choiceKey.set(mediumCmdCompleted)))) commandResponseManager.updateSubCommand(id, Completed(id)) case id if id == longSetup.runId ⇒ currentStatePublisher .publish(CurrentState(longSetup.source, StateName("testStateName"), Set(choiceKey.set(longCmdCompleted)))) commandResponseManager.updateSubCommand(id, Completed(id)) }
- Java
-
// An original command is split into sub-commands and sent to a component. The result of the command is // obtained by subscribing to the component with the sub command id. ICommandService componentCommandService = runningHcds.get(componentInfo.getConnections().get(0)).get(); componentCommandService.submit(subCommand2, Timeout.durationToTimeout(FiniteDuration.apply(5, TimeUnit.SECONDS))) .thenAccept(commandResponse -> { if (commandResponse instanceof CommandResponse.Completed) { // As the commands get completed, the results are updated in the commandResponseManager commandResponseManager.updateSubCommand(subCommand2.runId(), commandResponse); } else { // do something } });
It may be the case that the component wants to avoid automatic inference of a command based on the result of the sub-commands. It should refrain from updating the status of the sub-commands in this case and update the status of the parent command directly as required.
query
Query for the result of a command that is already present in the component’s CommandResponseManager.
- Scala
-
// query CommandResponseManager to get the current status of Command, for example: Accepted/Completed/Invalid etc. commandResponseManager .query(controlCommand.runId) .map( _ ⇒ () // may choose to publish current state to subscribers or do other operations ) // Return response Started(controlCommand.runId)
- Java
-
// query CommandResponseManager to get the current status of Command, for example: Accepted/Completed/Invalid etc. commandResponseManager .jQuery(subCommand.runId(), Timeout.durationToTimeout(FiniteDuration.apply(5, "seconds"))) .thenAccept(commandResponse -> { // may choose to publish current state to subscribers or do other operations });
subscribe
Subscribe for the result of a command that is already present in the component’s CommandResponseManager and perform action on the change in status.
- Scala
-
// subscribe to the status of original command received and publish the state when its status changes to // Completed commandResponseManager.subscribe( controlCommand.runId, { case Completed(_) ⇒ currentStatePublisher.publish( CurrentState(controlCommand.source, StateName("testStateName"), Set(choiceKey.set(longRunningCmdCompleted))) ) case _ ⇒ } )
- Java
-
// subscribe to the status of original command received and publish the state when its status changes to // Completed commandResponseManager.jSubscribe(subCommand.runId(), commandResponse -> { if (commandResponse instanceof CommandResponse.Completed) { Key<String> stringKey = JKeyType.StringKey().make("sub-command-status"); CurrentState currentState = new CurrentState(sc.source().prefix(), new StateName("testStateName")); currentStatePublisher.publish(currentState.madd(stringKey.set("complete"))); } else { // do something } });