Synchronous versus Asynchronous Calls in vSphere API
In a previous article Top 10 Best Practices Using VMware VI and vSphere SDK, I mentioned synchronous versus asynchronous calls in the second best practice “Choose Right APIs.” But no detail was provided there. In this article, which is based on my book VMware VI and vSphere SDK , I discuss all the details.
Some methods defined on managed objects in vSphere API are asynchronous, meaning they return right away whether the operations are done successfully or not. That makes sense for long-running operations; you don’t want to block your current thread by waiting for the return of the call, and you might want to cancel it before it’s done.
Lost VMs or Containers? Too Many Consoles? Too Slow GUI? Time to learn how to "Google" and manage your VMware and clouds in a fast and secure HTML5 App.
For these asynchronous methods, the VI SDK provides a way to track the progress and results after the invocation is returned. As a naming convention, a long-running asynchronous method has _Task as a suffix in the method name, and it returns MOR to a Task. With MOR pointing to the Task object, you can track the progress and even get the result of the operation. For example, the cloneVM_Task() method defined in VirtualMachine is a long-running method that returns MOR pointing to a Task managed object.
In your application code, you can choose to ignore the MOR task and move on to other things, wait for the task to be finished before moving on, or spawn a thread to monitor the task and move on.
Note: The asynchronous methods lead to an interesting phenomenon with fault handling. Because the asynchronous method returns right away, it doesn’t give you a runtime fault. But the signature has the fault, so you have to handle it even though it doesn’t happen in the asynchronous call. The asynchronous method does do preliminary checking of the parameters, so you still get faults such as InvalidArgument. If the fault occurs after the Task is returned, you can get hold of the info.error property of the Task. The property is of LocalizedMethodFault; it’s not a fault type but a data type wrapping a fault.
For the asynchronous methods, you can get more when the Task is finished. You can tell whether the operation is successful and if so retrieve a result from the info property of the Task managed object.
Not all the long operations are designed as asynchronous methods. For example, querying huge performance data using the queryPerf() method could be a long operation. But it’s not an asynchronous method. To avoid performance problems, you should query as little information as possible with these calls. Of course, most synchronous methods take no time to finish. You can use them comfortably.
It is worthwhile to mention the waitForUpdate() method of PropertyCollector, which is designed to block and returns only when the object it watches has a change. This method allows you to be notified instead of requiring you to keep polling. Because it blocks, you should have a separate thread for this method in your GUI application.