'Wrapper to call an asynchronous task.
- run from the main request
@param task: The function which should be run
- async if a worker is alive
@param args: The list of unnamed args to send to the function
@param vars: The list of named vars to send to the function
@param timeout: The length of time available for the task to complete
- default 300s (5 mins)'

def async(self, task, args=None, vars=None, timeout=300):

    if (args is None):
        args = []
    if (vars is None):
        vars = {}
    tasks = current.response.s3.tasks
    if (not tasks):
        return False
    if (task not in tasks):
        return False
    if (not self._is_alive()):
        _args = []
        for arg in args:
            if isinstance(arg, (int, long, float)):
                _args.append(str(arg))
            elif isinstance(arg, basestring):
                _args.append(('%s' % str(json.dumps(arg))))
            else:
                error = ('Unhandled    arg    type:    %s' % arg)
                current.log.error(error)
                raise HTTP(501, error)
        args = ','.join(_args)
        _vars = ','.join([('%s=%s' % (str(var), str(vars[var]))) for var in vars])
        if args:
            statement = ("tasks['%s'](%s,%s)" % (task, args, _vars))
        else:
            statement = ("tasks['%s'](%s)" % (task, _vars))
        null = None
        exec statement
        return None
    auth = current.auth
    if auth.is_logged_in():
        vars['user_id'] = auth.user.id
    record = current.db.scheduler_task.insert(application_name=('%s/default' % current.request.application), task_name=task, function_name=task, args=json.dumps(args), vars=json.dumps(vars), timeout=timeout)
    return record
