Azure / azure-webjobs-sdk

Azure WebJobs SDK

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Need to make output binding order deterministic

mathewc opened this issue · comments

We have a BindStepOrder enum that bindings have traditionally used to enforce an ordering beyond parameter order. E.g. Queue/ServiceBus bindings declare BindStepOrder.Enqueue to ensure that those operations happen AFTER any other output bindings. This ensures that for example a blob that you output from your function happens BEFORE a queue message pointing to that blob is enqueued.

Recent work to replat core bindings (e.g. Queue/Table) have changed the way that this behaves. We need to move the bindings back to the way they behaved before at a minimum (i.e. retain the BindStepOrder capabilities allowing certain bindings to declare an order that overrides parameter order).

We should also verify that our parameter ordering uses a stable sort.

Related to #921

Re "stable sort", SortParameterNamesInStepOrder calls Array.Sort which is "unstable" (meaning it can reorder the parameters within the same sort-equivalence).
https://github.com/Azure/azure-webjobs-sdk/blob/dev/src/Microsoft.Azure.WebJobs.Host/Executors/FunctionExecutor.cs#L810

In practice, this is stable for small values.

The goals here:

  1. We want determinism / predictability (safety is a feature)
  2. There’s no transactions, so if we have N outputs, we must determine what order to flush them in. Ideally, enforce an order that guarantees determinism.
  3. We could let the customer specify an ordering (ie, order of parameters), but can we protect them if they get it wrong?

The rule then is:
Given 2 parameters A and B, if (A is triggerable) and (A can depend on B), flushing A should happen after flushing B.
“A depends on B” means “processing A’s trigger may depend on B’s contents”

Nothing depends on Queue (put another way, only the queue trigger can read the queue message contents); so Q is always safe to be “last”.