本篇聚焦「互動 API」:Signal、Query、Update,看如何透過 API 與有狀態且可重播的 Workflow 互動,達成流程的推進。
並提供對照表、範例與設計指南協助在不同情境下使用正確的 API。
簡介:
方法 | 類型 | 同步性 | 功能 | 輸入參數 | 回傳型別 | 適用情境 |
---|---|---|---|---|---|---|
Query(typed) | 物件 | 同步 | 讀取狀態,無副作用 | stub.queryMethod(args...) |
T |
查詢進度/狀態 |
Query(untyped) | 物件 | 同步 | 以名稱字串查詢 | stub.query("queryType", T.class, args...) 或 TypeRef<T> |
T |
跨程式/缺介面 |
Signal(typed) | 物件 | 非同步 | 投遞事件,不保證即時回應 | stub.signalMethod(args...) |
void |
通知/觸發狀態更新 |
Signal(untyped) | 物件 | 非同步 | 以名稱字串投遞 | stub.signal("signalName", args...) |
void |
跨程式/缺介面 |
SignalWithStart | 物件 | 非同步 | 不存在則啟動並送 Signal;存在則直接送 Signal | stub.signalWithStart(signalName, signalArgs[], startArgs[]) |
WorkflowExecution |
upsert 語意,避免重複建立 |
Update(typed) | 物件 | 可選 | 強語意更新,保證回覆 | stub.updateMethod(args...) |
T 或 void |
要立即知道成功/失敗 |
Update(untyped, start) | 物件 | 非同步 | 啟動更新並回傳 handle | stub.startUpdate(UpdateOptions, args...) |
WorkflowUpdateHandle<T> |
先發起,稍後再取結果 |
ExecuteUpdateWithStart | 物件 | 可選 | 不存在則啟動並送 Update;可選擇是否等待結果 | stub.executeUpdateWithStart(UpdateOptions, updateArgs[], startArgs[]) |
T |
upsert 並更新狀態 |
StartUpdateWithStart | 物件 | 非同步 | 不存在則啟動並「啟動 Update」回傳 handle | stub.startUpdateWithStart(UpdateOptions, updateArgs[], startArgs[]) |
WorkflowUpdateHandle<T> |
upsert 後稍後再取結果 |
// typed
MyWorkflow stub = client.newWorkflowStub(MyWorkflow.class, options);
int count = stub.getPendingCount();
// untyped
WorkflowStub u = client.newUntypedWorkflowStub("MyWorkflow", options);
int count2 = u.query("getPendingCount", Integer.class);
// typed
MyWorkflow stub = client.newWorkflowStub(MyWorkflow.class, options);
stub.addItem("item-1");
// untyped(可跨程式/跨語言)
WorkflowStub u = client.newUntypedWorkflowStub("MyWorkflow", options);
u.signal("addItem", "item-1");
// SignalWithStart:若 workflow 不存在 → 啟動並送 signal;存在 → 直接送 signal
WorkflowExecution exec = u.signalWithStart(
"addItem",
new Object[] { "item-1" }, // signal args
new Object[] { "wf-123" } // start args(對應 @WorkflowMethod 參數)
);
// typed(等待結果)
MyWorkflow stub = client.newWorkflowStub(MyWorkflow.class, options);
boolean ok = stub.approve("order-123");
// untyped(先發起再等:start)
WorkflowStub u = client.newUntypedWorkflowStub("MyWorkflow", options);
WorkflowUpdateHandle<Boolean> handle = u.startUpdate(
UpdateOptions.newBuilder().setUpdateName("approve").build(),
new Object[] { "order-123" }
);
Boolean ok3 = handle.getResult();
// ExecuteUpdateWithStart:若不存在 → 啟動並送 update;可選擇等待結果
Object result = u.executeUpdateWithStart(
UpdateOptions.newBuilder().setUpdateName("approve").build(),
new Object[] { "order-123" }, // update args
new Object[] { "wf-123" } // start args
);
workflowId
)updateId
;Signal/Query 規劃自然鍵避免重送歧義本篇重點在於了解互動過程的細節,讓流程可以順利可持久化的並完成一致性流程推進。
下一篇將進入 Entity Pattern Workflow 了解「每個 Entity 一個 Workflow」的實際操作。