全部產品
Search
文件中心

CloudFlow:輸入和輸出

更新時間:Jul 06, 2024

本文介紹了輸入和輸出的基本知識,您可以參見本文樣本進行操作。

流程和步驟

通常流程的多個步驟之間需要傳遞資料。和函數式程式設計語言類似,FDL的步驟類似於函數,它接受輸入(Input),並返回輸出(Output),輸出會儲存在父步驟(調用者)的本地(Local)變數裡。其中,輸入和輸出的類型必須是JSON對象格式,本地變數的類型因步驟而異。例如任務步驟把調用Function Compute函數的返回結果作為本地變數,並行步驟把它所有分支的輸出(數組)作為本地變數。步驟的輸入、輸出和本地變數總大小不能超過32 KiB,否則會導致流程執行失敗。

如果一個步驟包含另一個步驟,則稱外層步驟為父步驟,被包含步驟為子步驟。最外層步驟的父步驟是流程。如果兩個步驟的父步驟相同,則這兩個步驟是同級步驟。

流程和步驟都有輸入、輸出和本地變數。他們的轉換關係如下:

  • 步驟輸入映射(inputMappings)將父步驟的輸入和本地變數映射為子步驟的輸入。
  • 步驟輸出映射(outputMappings)將當前步驟的輸入和本地變數映射為當前步驟的輸出。
  • 流程輸入映射(inputMappings)將使用者執行流程時的輸入映射為流程的輸入。
  • 流程輸出映射(outputMappings)將流程輸入和本地變數映射為流程的輸出。

一個父步驟的本地變數儲存了其所有子步驟輸出的合并,如果輸出中有同名索引值,則後執行步驟會覆蓋前執行步驟的結果。在大多數情況下,您不需要指定輸入和輸出映射,而使用預設的映射行為。他們的轉換關係如下:

  • 在不指定輸入映射情況下,子步驟的輸入是其父步驟輸入和父步驟本地變數的合并(如果本地變數和輸入有同名索引值,則本地變數會覆蓋輸入)。
  • 在不指定輸出映射情況下,除並行步驟和並行迴圈步驟外的其它步驟都會將本地變數作為輸出。

如果您想更好地控制輸入和輸出,則需要瞭解詳細的映射規則。

下面樣本流程的輸入輸出映射如圖所示。其中step1是step2和step3的父步驟。step1和step4是最外層步驟。

version: v1
type: flow
steps:
  - type: parallel
    name: step1
    branches:
      - steps:
        - type: pass
          name: step2
      - steps:
        - type: pass
          name: step3
  - type: pass
    name: step4      
flow-io-mappings-v0

為了便於理解,這些映射可以用下面的代碼描述。

func flow(input0 Input) (output0 Output) {
  local0 := {}
  input1 := buildInput(step1InputMappings, input0, local0)
  output1 := step1(input1)
  save(local0, output1)
  input4 := buildInput(step4InputMappings, input0, local0)
  output4 := step4(input4)
  save(local0, output4)
  return buildOutput(flowOutputMappings, input0, local0)
}
func step1(input1 Input) (output1 Output) {
  local10 := {}
  input2 := buildInput(step2InputMappings, input1, local10)
  output2 := step2(input2)
  save(local10, output2)
  local11 := {}
  input3 := buildInput(step3InputMappings, input1, local11)
  output3 := step3(input3)
  save(local11, output3)
  return buildOutput(step1OutputMappings, [local10, local11])
}
func step2(input2 Input) (output2 Output) {
}
func step3(input3 Input) (output3 Output) {
}
func step4(input4 Input) (output4 Output) {
}       

在這個例子中,流程包含了兩個子步驟:step1step4step1是一個並行步驟,它包含step2step3兩個子步驟。

  1. 系統在開始執行流程時,根據流程的輸入映射將StartExecution輸入轉換為流程輸入(input0)。
  2. flow開始時,其local0為空白。
  3. 系統根據step1的輸入映射(step1InputMappings)來為它準備輸入input1,映射的源來自flow的輸入input0和本地變數local0
  4. 調用step1,傳入輸入input1step1返回輸出output1
    • step1開始時,其local0為空白 。因為step1是一個並行步驟,所以每個分支都對應一個本地變數,從而避免並發訪問的問題。
    • 系統根據step2的輸入映射(step2InputMappings)來為它準備輸入input2,映射的源來自step1的輸入input1和本地變數local10
    • 調用step2,傳入輸入input2step2返回輸出output2
    • 系統將step2的輸出儲存到step1的本地變數local10
    • 同樣的,系統調用step3並將結果儲存在step1的本地變數local11
  5. 系統將step1的輸出儲存到flow的本地變數local0
  6. 類似的,系統根據step4的輸入映射來為它準備輸入input4,映射的源來自flow的輸入input0和本地變數local0
    說明 這時的本地變數local0可能已經包含了step1的輸出,從而實現了step1step4的資料傳遞。
  7. 調用step4,傳入輸入input4step4返回輸出output4
  8. 系統將step4的輸出儲存到flow的本地變數local0
  9. 最後,系統根據流程的輸出映射將local0轉換為流程輸出。

類型定義

輸入映射和輸出映射都是由targetsource組成的數群組類型,其中source定義了參數來源,根據不同的映射取值不同,例如$input.key表示參數來自輸入input$.key所對應的值,target定義了目標參數名稱。 當source$開始表示該值通過JSON Path方式指定(可以通過這個工具調試JSON Path),系統會根據該路徑解析為具體值,否則認為該值是常量類型。

  • 來源(Source)

    來源支援使用常量作為source值,可以使用數字(number)、字串(string)、布爾(boolean)、數組(array)、對象(object)或者null類型。

    下面樣本映射的source使用了不同類型的常量,其產生的輸出如下所示。

    outputMappings:
      - target: int_key
        source: 1
      - target: bool_key
        source: true
      - target: string_key
        source: abc
      - target: float_key
        source: 1.234
      - target: null_key
        source: null
      - target: array1
        source: [1, 2, 3]
      - target: array2
        source:
          - 1
          - 2
          - 3
      - target: object1
        source: {a: b}
      - target: object2
        source:
          a:           
    {
      "array1": [1, 2, 3],
      "array2": [1, 2, 3],
      "bool_key": true,
      "float_key": 1.234,
      "int_key": 1,
      "null_key": null,
      "object1": {
        "a": "b"
      },
      "object2": {
        "a": "b"
      },
      "string_key": "abc"
    }            
  • 目標

    目標只能是一個字串類型常量。

輸入映射

輸入映射將父步驟的輸入($input)、父步驟的本地變數($local)、或者常量轉換為子步驟的輸入。如果沒有指定輸入映射,父步驟的輸入和父步驟的本地變數合并後會被當做子步驟的輸入。如果父步驟的輸入和父步驟的本地變數中有相同名稱,則新的輸入中採用本地變數中的名或值。

inputMappings:
  - target: key1
    source: $input.key1
  - target: key2
    source: $local.key2
  - target: key3
    source: literal         
輸入 $input本地變數 $local輸入映射子步驟輸入
{
"key1":"value1"
}
{
"key2":"value2"
}
inputMappings:
  - target: key1
    source: $input.key1
  - target: key2
    source: $local.key2
  - target: key3
    source: literal
{
"key1":"value1"
"key2":"value2"
"key3":"literal"
}
{
"key1":"value1"
}
{
"key2":"value2"
}
{
"key1":"value1"
"key2":"value2"
}
{
"key1":"value1"
}
{
"key1":"value2"
}
{
"key1":"value2"
}

輸出映射

輸出映射將當前步驟的輸入($input)、本地變數($local)、或者常量轉換為本地步驟的輸出。如果沒有指定輸出映射,對於選擇步驟和迴圈步驟,它們的本地變數會被當做其輸出,任務步驟會將具體任務執行結果作為輸出。由於並行(Parallel)和並行迴圈(ForEach)步驟的本地變數是數群組類型,所以您需要定義輸出映射將數群組轉換結果成JSON對象格式,預設不會輸出它們的本地變數。具體介紹可參見步驟描述。

outputMappings:
  - target: key1
    source: $input.key1
  - target: key2
    source: $local.key2
  - target: key3
    source: literal          
輸入 $input本地變數 $local輸出映射步驟輸出
{
"key1":"value1"
}
{
"key2":"value2"
}
outputMappings:
  - target: key1
    source: $input.key1
  - target: key2
    source: $local.key2
  - target: key3
    source: literal
{
"key1":"value1"
"key2":"value2"
"key3":"literal"
}
{
"key1":"value1"
}
[
  {
    ”key2”:”value2.1”
  },
  {
    ”key2”:”value2.2”
  }
]
outputMappings:
  - target: key1
    source: $input.key1
  - target: key2
    source: $local[*].key2
  - target: key3
    source: literal
{
  ”key1”:”value1”,
  ”key2”:[“value2.1”,”value2.2”],
  ”key3”:”literal”
}
{
"key1":"value1"
}
{
"key2":"value2"
}
{
"key2":"value2"
}

輸出如何儲存到父步驟本地變數

子步驟的輸出($output)會被併入父步驟的本地變數。如果二者有重複名稱,則輸出中的名或值會覆蓋本地變數相應名或值。

輸出 $output父步驟本地變數 $local更改後父步驟本地變數
{
"key1":"value1"
}
{
"key2":"value2"
}
  {
    ”key1”:”value1”
  },
  {
    ”key2”:”value2”
  }
{
"key1":"value11"
}
  {
    ”key1”:”value1”
  },
  {
    ”key2”:”value2”
  }
  {
    ”key1”:”value11”
  },
  {
    ”key2”:”value2”
  }