Skip to content

RussellLuo/orchestrator

Repository files navigation

Orchestrator

A Go library for service orchestration, inspired by Conductor.

Core Concepts

Task

Tasks are the fundamental building blocks of Orchestrator. They are similar to primitive types or statements in a programming language.

Typically, a task accepts an input and returns an output. Each parameter in the input can be a literal value or an expression.

Built-in tasks:

Flow

A flow is used to define a piece of logic, which usually consists of one or more tasks. Flows are similar to functions or routines in a programming language.

In Orchestrator, a flow is essentially a composite task (i.e. a Serial task). Therefore, just like a task, a flow accepts an input and returns an output. Furthermore, a flow can be embedded into another flow by leveraging a Call task, thus serving as a sub-flow.

Expression

Expressions are used to extract values out of the flow input and other tasks in the flow.

For example, a flow is supplied with an input by the client/caller when a new execution is triggered. The flow input is available via an expression of the form ${input.<var>} (see dialects). Likewise, the output of a previously executed task can also be extracted using an expression (e.g. ${<task>.<output_var>}) for use in the input of a subsequent task.

Dialects

Currently supported expression dialects:

  • Starlark

    In addition to Starlark's built-in functions, there are some more pre-declared functions:

    • getenv(key): Retrieve the value of the environment variable named by the key.
    • isiterator(v): Whether the given value v is an Orchestrator Iterator.
    • jsonencode(v): Encode the given value v to a JSON string (go.starlark.net/lib/json).
    • jsondecode(v): Decode the given JSON string to a value (go.starlark.net/lib/json).

    Examples:

    ${input.value}  // Value from the input.
    ${tool.status == 200}  // Whether the status code (from an HTTP task `tool`) is 200
    ${len(tool.body.entities)}  // Length of the response entities (from an HTTP task `tool`)
    ${[s*2 for s in input.scores]}  // List comprehension
    ${{k: v.upper() for k, v in input.properties.items()}}  // Dictionary comprehension
    
  • Expr

    (- expand -)

    Examples:

    #{input.value}  // Value from the input.
    #{tool.status == 200}  // Whether the status code (from an HTTP task `tool`) is 200
    #{len(tool.body.entities)}  // Length of the response entities (from an HTTP task `tool`)
    //#{[s*2 for s in input.scores]}  // UNSUPPORTED
    //#{{k: v.upper() for k, v in input.properties.items()}}  // UNSUPPORTED
    
  • JSONPath (spec and implementation)

    (- expand -)

    Examples:

    @{input.value}  // Value from the input.
    //@{tool.status == 200}  // UNSUPPORTED
    //@{len(tool.body.entities)}  // UNSUPPORTED
    //@{[s*2 for s in input.scores]}  // UNSUPPORTED
    //@{{k: v.upper() for k, v in input.properties.items()}}  // UNSUPPORTED
    

Flow Builders

Orchestrator provides three ways to build a flow.

Go

flow := builtin.NewSerial("get_todo_user").Timeout(3*time.Second).Tasks(
	builtin.NewHTTP("get_todo").Timeout(2*time.Second).Get(
		"https://jsonplaceholder.typicode.com/todos/${input.todoId}",
	),
	builtin.NewHTTP("get_user").Timeout(2*time.Second).Get(
		"https://jsonplaceholder.typicode.com/users/${get_todo.body.userId}",
	),
).Build()

See Example for the complete example.

YAML

name: get_todo_user
type: serial
timeout: 3s
input:
  tasks:
  - name: get_todo
    type: http
    timeout: 2s
    input:
      method: GET
      uri: https://jsonplaceholder.typicode.com/todos/${input.todoId}
  - name: get_user
    type: http
    timeout: 2s
    input:
      method: GET
      uri: https://jsonplaceholder.typicode.com/users/${get_todo.body.userId}

See Example (Yaml) for the complete example.

JSON

{
  "name": "get_todo_user",
  "type": "serial",
  "timeout": "3s",
  "input": {
    "tasks": [
      {
        "name": "get_todo",
        "type": "http",
        "timeout": "2s",
        "input": {
          "method": "GET",
          "uri": "https://jsonplaceholder.typicode.com/todos/${input.todoId}"
        }
      },
      {
        "name": "get_user",
        "type": "http",
        "timeout": "2s",
        "input": {
          "method": "GET",
          "uri": "https://jsonplaceholder.typicode.com/users/${get_todo.body.userId}"
        }
      }
    ]
  }
}

See Example (Json) for the complete example.

Documentation

Checkout the Godoc.

License

MIT

Releases

No releases published

Packages

No packages published

Languages