def run(s, runnable, *args, **kwargs):
    """Submits Runnable objects to the PoolExector.

        Using Runnable objects, you have more control and verbosity.
        Useful when things go wrong (we know it always happens).
        If you are in a hurry, submit a function using :py:func:`run_fn`.
        """
    future = s._executor.submit(runnable.run, *args, **kwargs)
    s._future_runnables[future] = runnable
    future.add_done_callback(s._done_runnable)
    return future
