11.12.1.Synchronization

It is possible to add requests to a queue at all times. It is also possible to check for the result of any request made so far, by either blocking to wait for it or just checking its status.

aq_wait (in aq any, in req_no int, in block int, out err any) returns any

The aq_wait function takes the queue, a request number returned by aq_request, a blocking flag and an output parameter for the error state.

If there was no error, the error state is set to 0. If the procedure was undefined, the error state is set to 2. If there was a SQL state signalled from the procedure called on the worker thread, the error state is set to an array of three elements: The integer 3, the SQL state string and the text of the message. If aq_wait is terminated by an external event, then an error indicating this is signalled and the state waited for is lost. This can only happen when all transactions are killed by shutdown or going to a single user state.

If the blocking flag was zero and the request was not complete, then the error output parameter is set to 1 and 1 is returned.

Once aq_wait has retrieved a state, the state is no longer retained in the queue.

The aq_wait_all function allows waiting for all activity to complete but discards individual return states. If some of running activities is terminated by sql error, this error will be raised in the thread executing aq_wait_all function call.

Note that it is possible to get a deadlock between the requesting thread and a worker thread and that this deadlock cannot be detected by the database engine since this does not involve a cycle in database locks themselves. Thus, aq_wait signals an error if the thread calling it holds database locks. Manually committing or rolling back before calling aq_wait is necessary if the thread can belong to a transaction that holds locks.

Thus, it is most practical to explicitly commit all work on the requesting thread before calling aq_wait or aq_wait_all.

create procedure taq_all (in x int, in thrs int := 1)
{
  declare aq, res, err any;
  declare n int;
  aq := async_queue (thrs);
  for (n:= 0; n < x; n:=n+1)
    {
      res := aq_request (aq, 'DB.DBA.INS1', vector (n));
    }
  aq_wait_all (aq);
}

-- This procedure is guaranteed to wait for all requests to be completed but will discard individual error states.