版が固定されたForm仕様
この版で固定されたURLの規範本文は日本語です。原文を読む。公開はHostやproviderの対応を意味しません。
DurableWorkflow 0.3.0
このFormはModuleWorker 0.3.0がexportする一つの Workflow classと、そのinstance ID空間・履歴を表す。instanceはこのResourceの実行dataで あり、個別のTakoform Resourceではない。コードは有効な WorkerDeployment 0.4.0のweighted WorkerVersion 0.5.0から選ぶ。 forms.takoform.com/v2のこのFormをHostが支持すると言うには、この章のinstance、 durable step、replay、停止と削除の全条件を満たさなければならない。
入力、観測、CRUD
specはworker:{"resourceUid":string}とclassName:stringだけを必須とする。 classNameは^[A-Za-z_$][A-Za-z0-9_$]{0,63}$。既定値も秘密入力もない。未知キー、 null、入れ子参照の余分なキーを拒否する。Hostは参照先が同じHost・Spaceの ModuleWorker 0.3.0であり、呼出者に利用権限があると副作用前に確認する。 参照先Worker Resourceは作成時に存在しなければならない。Deploymentだけは未作成でも Workflowを作成できるが、全weighted Versionに正しいclassが揃うまでReadyでない。 UID参照は名前やlatestへ再解決しない。 Workflow作成要求の受理前に、有効なDeploymentの現在の配分と、先に受理された 未完了のDeployment作成・配分更新の適用予定をそれぞれ調べる。対象となる全weighted Versionは、このclassNameのWorkflow class ABIを満たさなければならない。classの 欠落・ABI不適合が確定した場合は409 dependency_conflictで副作用前に拒否し、既存の Deploymentとその配分を変更しない。対象Versionの検証が未完了で判定できない場合は 409 resource_busyで受理せず、未検証を不適合と断定しない。有効なDeploymentもその 未完了の作成・配分更新もなければ、先行作成を許し、正しいVersionが選ばれるまでは Readyにしない。受理済みOperationの結果は後からHTTPの事前拒否へ置き換えない。
specの例(UIDは説明用):
{
"worker": { "resourceUid": "worker-uid" },
"className": "ReportWorkflow"
}未観測のobservedは {}。確認済みならready:booleanと、queued、running、 sleeping、waiting、complete、errored、terminatedの各instance件数を持つ instanceCountsを返す。時点はobservedAtであり、GET時の即時照会を保証しない。 ready:trueは新規instanceを受理できることだけを表し、アプリの成功ではない。outputは {}。
作成はUIDと空のinstance ID空間を確保する。取得は管理記録と最後の観測を返す。 PUTは全体置換で、同じworkerとclassNameだけ許す。変更要求は副作用前に拒否し、 同一specの新しいキーは新しいOperation/generationを作り再照合する。コード昇格は Deploymentで行い、このResourceのPUTで既存履歴を改変・移行しない。
削除は、削除されていないWorkerVersionのworkflowBindingsからの参照がある間だけ 409 dependency_conflictで副作用前に拒否する。Versionがweightedか否かは問わない。 参照がなくなれば、このResourceの明示的なDELETEはそのUIDに属するqueued/running/ sleeping/waitingのinstanceも含めて廃止できる。Hostは新規create/event/wakeを閉じ、 実行ownerをfenceし、future continuationを取消し、childの物理的停止を確認してから、 このUIDの全instance ID・step履歴・未一致eventをpurgeする。terminal状態への事前移行や、 利用者による個別terminate()は必要ない。停止・fenceを証明できない間は成功にせず、 同じOperationで照合を続ける。古いowner tokenはその後commitできない。 他Resource、Worker、Version、外部dataを連鎖削除しない。削除後の同名再作成は新UID・ 空履歴である。結果不明時は元のIdempotency-Keyで同じOperationを照合し、別UIDを 作り直さない。短時間の並行変更はresource_busy、存続するBindingは dependency_conflictと区別する。
Caller Bindingとinstance
workflowBindings[].resourceからのenv.NAMEは次のsurfaceを提供する。
interface WorkflowBinding {
create(input: { id?: string; params?: DataDocument }): Promise<WorkflowInstance>;
get(id: string): Promise<WorkflowInstance>;
}
interface WorkflowInstance {
readonly id: string;
status(): Promise<{status: WorkflowStatus; output?: DataDocument;
error?: {reason: WorkflowFailure; message?: string}} >;
sendEvent(input: {type: string; payload?: DataDocument}): Promise<void>;
terminate(): Promise<void>;
}idは1〜256 Unicodeスカラー値。省略時にHostが一意なIDを発行する。既存の保持中IDを createへ渡すとinstance_existsで拒否し、応答を失ったcreateが同名の二重実行に化けない。 getは未知・保持期限後にunknown_instance。状態は正確にqueued、running、 sleeping、waiting、complete、errored、terminatedの七つである。outputは complete時だけ、errorはerrored時だけで、失敗したrunもstatus()自体は成功する。 failure reasonはrun_threw、step_failed、step_limit_exceeded、 lifetime_exceeded、step_definition_mismatchだけ。
全document(params、step結果、event payload、output)はplainまたはnull-prototypeの object rootで最大1024 own property、RFC 8785 canonical UTF-8で最大1048576 bytes。 内部はnull、boolean、有限数、Unicode文字列、同条件のobjectまたは穴のない通常配列に限る。 accessor、symbol、function、BigInt、非JSON値、循環、配列の余分なproperty、nested undefinedを拒否する。共有する非循環objectはよい。getterやtoJSONを実行せずdescriptor を調べて直列化する。省略できるdocument全体のundefinedだけを「なし」とみなす。 不正paramsはinvalid_params、容量超過はdocument_too_large。未知の入力キーは拒否する。
sendEventは1〜256文字のtypeと任意のpayloadをdurably受理し、instanceごとの受理順を 付けてから成功する。消費完了までは保証しない。terminal instanceはinstance_terminal、 未知IDはunknown_instance。待機中の一致waitに直接渡せる場合を除き、未消費eventは最大 1024件かつ保存した{type,payload?}のcanonical UTF-8総量1048576 bytesで、超過は event_queue_fullとして受理しない。terminal遷移では未一致eventをpurgeする。 terminate()はownerをfenceし、future continuationを取消し、物理的に実行contextが停止して からterminatedを公開して成功する。停止を証明できなければ成功を返さない。すでにterminal なら成功する。caller操作のbackend不達はbackend_unavailableで識別する。
Class ABI、replay、step
全weighted Versionのmain moduleはclassNameのconstructibleなnamed exportとcallableな prototype runを持つ。Hostは新しい実行contextごとにnew Export(env)を作り、 instance.run({instanceId,params?},step)を一回呼ぶ。envはそのVersionの宣言済み環境 のみで、管理controlは入れない。戻り値はdocumentまたはundefined(直接またはPromise)で、 {output:...}というwrapperを要求しない。constructor/module評価を含めstep外のコードは 履歴に対し決定的で副作用を起こさない。replayは新しいobject/closure/module stateから始まり、 前contextの変数や未settle Promiseは残らない。各contextは開始時点の配分から一版を選び 固定する。retry/wakeは新版を選び得るため、作者は履歴のstep name・効果・出力との互換性を 保つ。Hostは履歴を書き換えないし、その互換性を一般に証明できない。
stepはこのinstance/contextに束縛され、アプリからinstanceIdを渡さない。 step.do(name,effect,retryPolicy?)、step.sleep(name,seconds)、 step.waitForEvent(name,{type,timeoutSeconds})の三操作だけを持つ。nameとevent typeは 1〜256 Unicodeスカラー値。同時に重なるstep、未settle stepを残したrunのsettlement、 未完了名の異種再利用はcatchできないstep_definition_mismatchで実行を止める。 完了済み名は成功・失敗を問わず記録結果でreplayし、新たな効果を起こさない。 nameを先に検証し、完了済み名の残りの引数は使わない。未完了名の不正なJS引数はTypeError、 同種の保留stepは最初に保存した設定を維持する。最多1024 step、instance寿命は作成から 31536000秒。上限・期限はHost制御で、アプリがcatchして延命できるsentinelではない。 doはPromise<DataDocument | undefined>、sleepはPromise<void>、 waitForEventはPromise<DataDocument | undefined>を返す。最後の値は一致eventの payloadそのもので、payloadが無ければundefinedである。{payload:...}や {result:...}というwrapperは返さない。失敗時は下記のHost ErrorでPromiseを拒否する。
do: effectは零引数callableで、結果はdocumentまたはundefined。retryPolicyを省けばmaxAttempts:1。指定時はmaxAttemptsが1〜100、initialDelaySeconds既定0、backoff既定constant(またはexponential)、maxDelaySeconds既定43200。delayは0〜43200整数で、失敗した試行kの次のdelayは constantならmin(maxDelaySeconds,initialDelaySeconds)、exponentialならmin(maxDelaySeconds,initialDelaySeconds*2^(k-1))。各試行結果をcommitしてから次へ進む。 失敗後のretryは0 delayでもfresh contextで行う。効果の実行後、結果commit前にHostが死ぬと 効果は重複し得る。effectはidempotentに設計する。最終失敗はstep_failedを記録する。sleep:secondsは0〜31536000整数。初回の期限を固定する。未来のsleepはcontextを 停止してからsleepingを公開し、そのcontextのPromiseはresolveしない。期限後の新contextが 履歴へ成功を記録してresolveする。0秒は現contextで完了する。寿命より先へ短縮しない。waitForEvent:typeとtimeoutSeconds(1〜31536000整数)は必須。 instanceで最古の一致eventを原子的に消費しstep結果と一緒にcommitする。他typeは残り、 一eventを二waitに配らない。該当なしなら停止してからwaitingを公開する。同時刻なら timeout時刻に受理したeventが勝つ。期限後はwait_timeoutを記録し、新contextで拒否する。
StepのHost Errorは正確なsnake-case nameをown・読取専用・非列挙として持ち、由来は そのError object/contextへ非公開で紐づく。同じobjectの再throwは由来を保つが、nameを copyした別Errorは保たない。未捕捉の本物のstep_failedだけがterminal step_failedに なり、未捕捉wait_timeoutやTypeErrorなどはrun_threw。アプリが失敗を処理すれば completeにもなり得る。sleeping/waiting/terminalを公開する前にHostはコード停止を確認し、 古いownerのcommitをfenceする。処理後のstatusを先に見せてからコードを止めてはならない。 terminal履歴とIDはterminal遷移から少なくとも2592000秒保持する。その後はHostが 破棄でき、getがunknown_instanceになり得る。このWorkflow Resourceの明示的な DELETE成功だけが早期purgeの例外である。
本Form URLに新しい入力、status、step、失敗意味を暗黙追加しない。契約変更は別URLとする。