跳到主要内容

等待

本页介绍比基础功能更高级的 WaitFor 功能。

UntilAnyOfAllOf 不要求 condition ID。通过 Channel 定义读取 Channel 结果,并通过 Context 检查 Timer 结果。仅当其他 API 有要求时才添加 ID,例如 AnyCombinationOf,或按 ID 选择 Timer。

ConditionResults

WaitFor 完成后,Execute 可读取满足 Wait 的内容。对 Channel,用 GetConditionResults / results / condition_results 读取已发布消息。对 SubFlow,用 SubFlowResult / getConditionResults / condition_result 解码子 Flow 输出。

AnyOf 的各备选条件之间不会 greedy 地消费 Channel。Dex 只消费被选中用来满足 Wait 的 Channel condition。即使其他 Channel condition 也已满足,它们也不会消费消息,消息会继续留在队列中。

当多个 AnyOf 备选条件在同一次求值中均已满足时,Dex 按规范顺序选择第一个可行候选: 先按声明顺序检查 Timer condition,再按声明顺序检查 Channel condition,最后按声明顺序检查 SubFlow condition。前面尚未满足的 condition 不会阻塞后面已满足的 condition。因此,混合类型的 condition 不共享一个全局调用参数顺序。

AnyOf 表达当前备选条件之间的竞速。如果严格优先级要求继续等待高优先级输入,请只返回该 condition,等它解决后再开放其他条件。

Channel 结果

class ChannelWaitStep(Step[int]):
def __init__(self, approval: Channel[str]) -> None:
self.approval = approval

def wait_for(self, context: Context, input: int) -> Wait:
return Wait.any_of(
self.approval.for_one(),
Timer.by_duration(timedelta(seconds=input)),
)

def execute(self, context: Context, input: int) -> StepDecision:
if context.has_timer_fired():
return graceful_complete("approval timed out")
approvals = self.approval.results(context)
return graceful_complete(approvals[0])

例子: examples/python/dex_examples/primitives/channel/channel_flow.py

SubFlow 结果

def execute(self, context: Context, input: int) -> StepDecision:
result = SubFlow.get_condition_results(context)
output = result.single_output(int)
return graceful_complete(f"{SubFlow.get_flow_id(context)}|{output}")

例子: examples/python/dex_examples/primitives/subflow/parent_flow.py

anyCombinationOf

anyCombinationOf 表示 AND 组的 OR。每组内用 all_of 组合构建。

各组合之间不会 greedy 地消费 Channel。Dex 只消费被选中组合里的 Channel condition。即使其他组合也已满足,只属于其他组合的 Channel condition 也不会消费消息,消息会继续留在队列中。

AnyCombinationOf 与普通等待组合器不同:组合中的每个 Condition 都需要唯一的 condition ID

return Wait.any_combination_of(
ConditionCombination.of(
channel_a.for_one(condition_id="signal-a"),
Timer.by_duration(timeout, condition_id="timeout"),
),
ConditionCombination.of(
channel_b.for_one(condition_id="signal-b"),
),
)

例子: examples/python/dex_examples/primitives/wait_types/wait_types_flow.py

Step execution local

SetStepExecutionLocal 把值存在当前 StepExecution 上,供 ExecuteGetStepExecutionLocal 读取。适用于 WaitFor 算出了 Execute 需要的数据,又不想为此定义 Flow 级 Attribute

注意: Step input 本身会传给两个方法,不要把 input 再拷进 local。

def wait_for(self, context: Context, input: int) -> Wait:
context.set_step_execution_local("note", f"approval:{input}")
return Wait.until(approval.for_one())

def execute(self, context: Context, input: int) -> StepDecision:
note = context.get_step_execution_local("note", str)
return graceful_complete(note or "")

例子: examples/python/dex_examples/primitives/step_execution_local/step_execution_local_flow.py

Skip immediately

一种特殊的 Wait 是 SkipWaitImmediately。它不等待任何 condition。当构建 dynamic WaitFor 方法时,某些分支不需要等待,可以使用它。