'Asynchronously adds a Task or list of Tasks into this Queue.
This function is identical to add() except that it returns an asynchronous
object. You can call get_result() on the return value to block on the call.
Args:
task: A Task instance or a list of Task instances that will be added to
the queue.
transactional: If True, transactional Tasks will be added to the queue but
cannot be run or leased until after the transaction succeeds.  If the
transaction fails then the Tasks will be removed from the queue (and
therefore never run).  If False, the added task(s) are available to run
immediately; any enclosing transaction\'s success or failure is ignored.
rpc: An optional UserRPC object.
Returns:
A UserRPC object; call get_result to complete the RPC and obtain the Task
or list of Tasks that was supplied to this method. Successfully
queued Tasks will have a valid queue name and task name after the
call; such Task objects are marked as queued and cannot be added
again.
Note: Task objects returned from transactional adds are not
notified or updated when the enclosing transaction succeeds or fails.
Raises:
BadTaskStateError: if the Task(s) has already been added to a queue.
BadTransactionStateError: if the transactional argument is true but this
call is being made outside of the context of a transaction.
DuplicateTaskNameError: if a Task name is repeated in the request.
InvalidTaskError: if both push and pull tasks exist in the task list.
InvalidTaskNameError: if a Task name is provided but is not legal.
TooManyTasksError: if task contains more than MAX_TASKS_PER_ADD tasks.
TransactionalRequestTooLargeError: if transactional is True and the total
size of the tasks and supporting request data exceeds
MAX_TRANSACTIONAL_REQUEST_SIZE_BYTES.'

def add_async(self, task, transactional=False, rpc=None):

    try:
        tasks = list(iter(task))
    except TypeError:
        tasks = [task]
        multiple = False
    else:
        multiple = True
    has_push_task = False
    has_pull_task = False
    for task in tasks:
        if (task.method == 'PULL'):
            has_pull_task = True
        else:
            has_push_task = True
    if (has_push_task and has_pull_task):
        raise InvalidTaskError('Can    not    add    both    push    and    pull    tasks    in    a    single    call.')
    if has_push_task:
        fill_function = self.__FillAddPushTasksRequest
    else:
        fill_function = self.__FillAddPullTasksRequest
    return self.__AddTasks(tasks, transactional, fill_function, multiple, rpc)
