def serial_runner(self, tasks, task_args=None, task_kwargs=None, reducer=None):
    """A tasks that runs many subtasks syncronously, for batching up lots of small tasks.

    :param tasks: list of tasks to execute
    :param task_args: list of *args for each task
    :param task_kwargs: dict of **kwargs for each task
    :parma reducer: optional task to reduce the results with

    :returns: list or results, or results of reducer
    """
    task_args = task_args or []
    task_kwargs = task_kwargs or {}

    results = []
    for t in tasks:
        results.append(t.apply(args=task_args, kwargs=task_kwargs).result)

    if reducer:
        # List to reduce is first positional arg to task
        results = reducer.apply(args=(results,)).result

    return results