Listen for Tasks

Why listen for tasks?

Services need to receive a command from the Engine in order to execute any desired task. Every time a command is received, it will ensure that the sender is the Engine, then it will check if it can handle the command, and if so, it will execute it. Once executed, it will reply to the Engine with the result of the command.

Steps to follow

To implement tasks in your Service, you'll need to :

Task definitions

The first step is to declare the tasks that the service will be able to execute in the service's mesg.yml file. The events should be indexed by their ID and should describe the following attributes :

Attribute Type Default Description
name String id If the name of the task is not set, the name will be the ID of the task.
description String "" Description of the task: what the task is doing and why it is useful.
inputs map<id,Parameter> {} Map of inputs that the task needs in order to be executed.
outputs map<id,Outputs> {} Map of outputs that the task will emit. The task can declare multiple outputs but can only submit one output per execution.

Outputs

Attribute Type Default Description
name String id Name of the output. The default is the ID.
description String "" A description of the output: what kind of output, and how is it useful.
data map<id,Parameter> {} Map of the data the output will return.

Parameter (Input/Output)

Attribute Type Default Description
name String id Name or the parameter. The default is the ID.
description String "" Description of the parameter.
type Type String Type of the parameter.
object Parameter {} Nested parameters. Parameters can contain child parameters. It can only be defined when type is Object.
optional Boolean false If true, this parameter is considered as optional and might remain empty.
repeated Boolean false Define this parameter as an array of the type selected

Type of parameter

The parameter can be one of the following:

  • String
  • Boolean
  • Number
  • Object
  • Any

Example

Example of a task definition in a mesg.yml file :

...
tasks:
  taskX:
    name: "Task X"
    description: "This is the task X"
    inputs:
      inputX:
        name: "Input x"
        description: "Foo is a string"
        type: String
        optional: false
      inputY:
        name: "Input y"
        description: "Bar is an optional array of boolean"
        type: Boolean
        optional: true
        repeated: true
    outputs:
      outputX:
        name: "OutputX"
        description: "Output X"
        data:
          foo:
            name: "Output data x"
            description: "Description about output data x"
            type: String
          bar:
            name: "Output data y"
            description: "Description about output data y"
            type: Boolean
      outputY:
        ...
...

Listen for task executions

To listen for task to execute, the Service needs to open a stream with the Engine using the Protobuffer definition and gRPC. Every task received on the stream needs to be executed by the Service and the output submitted back to the Engine.

TIP

Consider listening for tasks when your service is ready. If your service needs to synchronize some data first, you should wait for this synchronization before listening for tasks.

Service.ListenTask

Name Type Required Description
token String Required The token given by the Engine as environment variable MESG_TOKEN
{
    "token": "TOKEN_FROM_ENV"
}
Name Type Description
executionID String A unique ID for the task that allows you to track the result in an asynchronous way
taskKey String Key of the task to execute (as in your mesg.yml file)
inputData String Inputs of the task serialized in JSON
{
    "executionID": "xxxxxx",
    "taskKey": "taskX",
    "inputData": "{\"inputX\":\"Hello world!\",\"inputY\":true}"
}

Submit outputs of task executions

Once the task execution is finished, the Service has to send the outputs of the execution back to the Engine using the Protobuffer definition and gRPC. Only one output can be submitted per execution even if the task has declared multiple outputs.

Service.SubmitResult

Name Type Required Description
executionID String required The executionID received from the listen stream.
outputKey String required The ID of the output as defined in the output's declaration.
outputData String required The output's data encoded in JSON. The data should match the one defined in the output's declaration.
{
    "executionID": "xxxxxx",
    "outputKey": "outputX"
    "outputData": "{\"foo\":\"super result\",\"bar\":true}"
}
Name Type Description
executionID String The ID of the execution.
{
    "executionID": "xxxxxx"
}

Examples

const mesg = require('mesg-js').service()

mesg.listenTask({
  // handler function of taskX
  taskX: (inputs, outputs) => {
    outputs.outputX({
      foo: inputs.inputX,
      bar: true
    })
  },
})
  .on('error', (error) => {
    console.error(error)
  })

See the MESG.js library for additional documentation

package main

import (
	"github.com/mesg-foundation/core/client/service"
)

type taskXInputs struct {
	InputX string `json:"inputX"`
	InputY []bool `json:"inputY"`
}

type taskXOutputX struct {
	Foo string `json:"foo"`
	Bar bool   `json:"bar"`
}

func main() {
	s, _ := service.New()

	s.Listen(
		service.Task("taskX", func(execution *service.Execution) (string, interface{}) {
			var inputs taskXInputs
			execution.Data(&inputs)

			return "outputX", taskXOutputX{
				Foo: inputs.InputX,
				Bar: true,
			}
		}),
	)
}

See the Go Service package for additional documentation

Get Help

You need help ? Check out the MESG Forum.

Last Updated: 5/2/2019, 4:33:14 AM