Starting workflows
IPgWorkflowClient is how your application code talks to PgWorkflows: start a run and
await its result, or fire-and-track with a handle.
Execute and wait
Section titled “Execute and wait”When you want the result inline:
var result = await workflows.ExecuteAsync<GreetingWorkflow, GreetingInput, string>( new GreetingInput("Postgres", 42));Start and track
Section titled “Start and track”When the workflow is long-running, start it and keep a handle:
var handle = await workflows.StartAsync<TrialOnboardingWorkflow, SignupInput, string>();
Console.WriteLine(handle.WorkflowRunId);
var result = await handle.GetResultAsync();The handle is cheap and stateless; the run itself lives in Postgres. It offers three
things: WorkflowRunId (store it, return it from your API), GetResultAsync (waits for
a worker to finish the run and returns the recorded result, throwing if the run failed),
and SignalAsync (delivers a signal to the run).
You don’t need to keep the handle around. Any process can signal a run later through the client and the stored id:
await workflows.SignalAsync(workflowRunId, "upgrade", new UpgradeDecision(true, "pro"));Idempotency keys
Section titled “Idempotency keys”Pass an idempotency key so a retried producer doesn’t start the same workflow twice:
var handle = await workflows.StartAsync<TrialOnboardingWorkflow, SignupInput, string>( idempotencyKey: $"signup:{signupId}");Starting with a key that was already used returns a handle to the existing run instead
of creating a new one, so a retried HTTP request or a redelivered queue message can’t
fork your workflow. Keys are scoped per workflow name: signup:42 on
TrialOnboardingWorkflow and on some other workflow are independent. A retry with the same key but
different input still returns the original run; PgWorkflows does not currently reject or compare
the new payload, so producers must keep a key bound to one logical request.
SignalAsync takes an idempotency key too, with the same effect: a redelivered signal
with a known key buffers nothing and the workflow consumes the payload once.