In certain circumstances it may be desirable to combine asynchronous calls and more conventional blocking I/O calls within the same function. Typically, such sections of code will be executed in the context of a threadable task as described in Section 6.2. However, this type of interworking can also be achieved for arbitrary threaded code provided that the blocking calls are not executed in the context of the main reactor thread.
In order to achieve this, each deferred event object implements the defer method on the Deferred interface. On calling this method, the callback chain will be automatically terminated with a synchronizing callback handler and the calling thread will be blocked until a deferred callback has been received. The callback data is then passed back as the return value for the defer method call as the calling thread is resumed. In the event that an errback condition is received, the exception which was passed as the errback parameter will be re-thrown in the context of the calling thread.
An example of mixing conventional blocking I/O calls with asynchronous APIs is shown in Listing 5.17. In this example, raw data is being read in 16 byte chunks from a standard Java input stream using blocking I/O. Within the loop, an asynchronous API is being used to write out the data. The asynchronous API call returns a deferred event object that on completion of the write operation will pass back a status value as the callback parameter.
In order to process the write status value within the loop, a call to the defer method is made, which causes execution of the loop to block until the status value has been returned from the asynchronous write operation. It is also possible that an exception could be passed back via the deferred errback handler, in which case it will be re-thrown and must be handled in the conventional manner. Note that the defer method declaration specifies that any exception derived from the base Exception class may be thrown, since exact details of the errback conditions which may be generated will be specific to a given asynchronous API call.