Outcome
Deferred OperationのStatusとTyped OutcomeをPublic ResourceまたはPHP Adapterから安全に取得する。
正常完了したDeferred Operationは、Operation IDごとに型付きOutcomeを保存します。Browserや外部ConsumerはPublic Status Resource、Generated Clientは.status()/.wait()を主経路にします。PHP AdapterからOutcomeだけを読む場合はPublic OutcomeReader Contractを使います。Persistence Payloadを独自にDecodeしたり、PostgreSQLのSchema Versionへ直接依存したりしないでください。
const current = await GenerateReport.status(operationId, options);
if (current.ok && current.kind === 'completed') {
current.data.outcome.reportName;
current.data.outcome.operationId;
}
Status Resultはaccepted/running/retry_scheduledをPending、completed/rejected/failed/dead_letteredをTerminalとして区別します。認可済みでRetention期限切れを証明できる場合は410 expired、UnknownとDenyは同じ404 operation_unavailableです。
PHP AdapterからOutcomeだけを読む
use BlackOps\Core\Identifier\OperationId;
use BlackOps\Outcome\OutcomeReader;
function reportResult(OutcomeReader $outcomes, string $operationId): ?ReportGenerated
{
$record = $outcomes->find(OperationId::fromString($operationId));
if ($record === null) {
return null;
}
$outcome = $record->outcome();
return $outcome instanceof ReportGenerated ? $outcome : null;
}
OutcomeRecordはOperation ID、復元済みOutcome、UTCへ正規化した完了時刻を持ちます。対象Recordがなければfind()はnullを返します。
nullの意味を区別する
nullだけでは次を区別できません。
- Operation IDが未知である
- Operationがまだ完了していない
- OperationがRejected/Failed/Dead Letterになった
- Outcomeの独立した保持期限を過ぎた
Public Status Query/HTTP Resourceはこれらを区別します。OutcomeReader::find()はOutcomeだけが必要なPHP Adapter向けなので、nullをStatus判定へ流用しません。Frameworkの非PublicなTableやPayload形式を利用者向けContractにしないでください。判定例はOutcome Statusを確認してください。
保存するOutcome
DeferredのCompletedだけがOutcome Recordを作ります。Inline completedはHTTP ResponseだけへOutcomeを返し、Outcome Recordを作りません。Rejected、Failed、Retry Scheduled、Dead Letter、Claim Lost、Grace Timeoutは成功Outcomeを作りません。値のないDeferred成功を表すEmptyOutcomeも型付きOutcomeとして保存します。
EphemeralOutcomeは例外です。HTTPへ一度だけ返すCredential ResponseなのでOutcome Rowを作らず、認可済みStatus Queryにもoperation_unavailableを返します。Journal上のEmptyOutcomeをDeclared Ephemeral Classへ復元しないでください。
PostgreSQL Storeは最初の完了結果を上書きせず、重複Saveを拒否します。未対応Schema Version、破損Payload、保存型の不一致、Outcomeを実装しない値はOutcomeStoreExceptionになります。
Retention
OutcomeのRetentionはTransport Payload、Journal、Dead Letterから独立しています。RetentionPolicy::outcomeRetention()はOutcomeRecord::completedAt()を基準に期限を判定します。ActiveなOperation Holdがある場合、PlannerとPurgeはOutcomeを対象外にします。
Purgeが成功すると、同じDatabase TransactionでPayloadを含まない監査Recordを保存し、RetentionPurgeResult::outcomesDeleted()へ削除件数を加算します。保持期間とHoldの運用はRetentionを確認してください。