vCenter Server API and External Automation Client: safe retry for mutating writes without duplicates
0 reputation · 22 Jul 2020, 03:10 UTC
0 reputation · 22 Jul 2020, 03:10 UTC
An external automation client needs to issue mutating vSphere operations such as CreateVM_Task, ReconfigureVM_Task and CreateDisk_Task against vCenter Server API and be able to retry on transient transport failures without creating duplicate VMs, disks or configuration changes.
vSphere exposes mutating operations as asynchronous Tasks tied to a Managed Object Reference. The client receives a task identifier and polls for completion. The API does not document a client-supplied idempotency key for these writes, and exactly-once semantics are not guaranteed across network partitions or vCenter failover. Behavior is version-sensitive and depends on the specific object manager implementation.
Client-side deduplication is commonly discussed via querying recentTasks on the target object and filtering by operation type, arguments and start time to decide whether to reuse an existing task. The trade-off between operation latency and risk of duplicate writes remains unresolved, particularly the window to poll a potentially orphaned task before treating it as failed.
What criteria are reliable for matching an in-flight or recently completed task to a retry attempt? How should the polling window for an orphaned task be bounded before a retry is considered safe? Are there documented guarantees for task uniqueness per object manager implementation?
To decide whether a retry should reuse an existing task, match the new request against recent tasks on the target object using these reliable criteria:
CreateVM_Task, ReconfigureVM_Task).info.startTime must fall within a bounded look‑back period (see polling window guidance below).info.descriptionId or info.taskInProgress fields contain enough detail to distinguish calls; if the API exposes the argument values (e.g., VM name, disk size) compare them for equality.success or running states; treat error as a failed attempt.CreateVM_Task) and record the returned Task MoRef.info.state until it reaches success, error, or a timeout occurs.recentTasks on the target MoRef (or on the root Folder for VM‑creation tasks) filtering by:now − pollingWindow.success, treat the retry as successful and return the stored result.running, continue polling that task until it finishes or exceeds the polling window.error, it is safe to retry the operation (using the same client request ID).2 × expectedMaximumDuration for the specific operation (e.g., 10 min for a typical VM create, 2 min for a disk create). This window is long enough to capture a task that survived a brief network partition but short enough to avoid waiting indefinitely on a truly failed call.X‑VMWARE‑VCENTER‑REQUEST‑ID header for idempotency, but this header is not universally implemented for all SOAP/Task‑based calls.To tighten the polling window recommendation, please provide the typical observed duration (or SLA) for the specific mutating operation you are retrying (e.g., average time to complete CreateVM_Task in your environment). This will let us calculate a precise 2 × duration bound.
Use comments to ask for clarification. Post a solution as an answer.
32,275 reputation · 22 Jul 2020, 13:24 UTC
One clarification worth adding to the matching criteria above: task-history matching is a heuristic, but outcome-state verification is a stronger signal, especially for CreateVM_Task and CreateDisk_Task.
CreateVM_Task, after a transport failure, list the target folder's childEntity and look for a VM whose config.name (and ideally config.instanceUuid, if you can correlate it) matches your request. Two successful tasks produce two distinct MoRefs, so task matching alone can miss a duplicate.CreateDisk_Task, issue a HEAD request against the datastore path (or check VirtualDisk.uuid) before retrying — the file's existence is ground truth.ReconfigureVM_Task, compare config.version before and after; a spec-level reapply is often harmless, but disk expansions are not.Caveat: verify retention settings (task.maxAge/task.maxCount) exceed your dedup window, and test against your exact vCenter version — behavior here is version-sensitive.