Futures

Satella contains a powerful interface to simplify writing Futures and enable the user to use functional-style code is a much simpler way.

Improved Futures

Satella presents the user with Future’s that can register callbacks that will change it’s value before returning it to waiting consumers. These futures are normal Python futures in their own right, and can be wait’ed upon.

class satella.coding.concurrent.futures.Future

A future that allows it’s callback handlers to change it’s result before presenting it to the user.

Use like this:

>>> fut = Future()
>>> fut.set_running_or_notify_cancel()
>>> def transform_future(future):
>>>     future.set_result(future.result() + 2)
>>> fut.add_pre_done_callback(transform_future)
>>> fut.set_result(2)
>>> assert fut.result() == 4
add_pre_done_callback(fn)

Attaches a callable that will be called just before the future finishes and can change the future’s result (or insert an Exception).

Args:
fn: A callable that will be called with this future as its only

argument just before the future completes or is cancelled.

chain(fun) Future

Schedule function to be called with the result of this future as it’s argument (or exception value if the future excepted).

Parameters:

fun – function to call

Returns:

self

exception(timeout: None) Type[Exception]

Return the exception raised by the call that the future represents.

Args:
timeout: The number of seconds to wait for the exception if the

future isn’t done. If None, then there is no limit on the wait time.

Returns:

The exception raised by the call that the future represents or None if the call completed without raising.

Raises:

CancelledError: If the future was cancelled. TimeoutError: If the future didn’t finish executing before the given

timeout.

on_failure(fun)

Schedule function to be called with the exception value that befall this future

Parameters:

fun – function to call

Returns:

self

on_success(fun) Future

Schedule function to be called with the result of this future as it’s argument only if this future succeeds.

Parameters:

fun – function to call

Returns:

self

result(timeout=None) T

Return the result of the call that the future represents.

Args:
timeout: The number of seconds to wait for the result if the future

isn’t done. If None, then there is no limit on the wait time.

Returns:

The result of the call that the future represents.

Raises:

CancelledError: If the future was cancelled. TimeoutError: If the future didn’t finish executing before the given

timeout.

Exception: If the call raised then that exception will be raised.

set_exception(exception)

Sets the result of the future as being the given exception.

Should only be used by Executor implementations and unit tests.

set_result(result: T) None

Sets the return value of work associated with the future.

Should only be used by Executor implementations and unit tests.

class satella.coding.concurrent.futures.WrappingFuture(source_future: Future)

A Satella future wrapping an existing Python future.

Use like:

>> wrapped = WrappingFuture(existing_python_future)

cancel() bool

Cancel the future if possible.

Returns True if the future was cancelled, False otherwise. A future cannot be cancelled if it is running or has already completed.

set_running_or_notify_cancel() bool

Mark the future as running or process any cancel notifications.

Should only be used by Executor implementations and unit tests.

If the future has been cancelled (cancel() was called and returned True) then any threads waiting on the future completing (though calls to as_completed() or wait()) are notified and False is returned.

If the future was not cancelled then it is put in the running state (future calls to running() will return True) and True is returned.

This method should be called by Executor implementations before executing the work associated with this future. If this method returns False then the work should not be executed.

Returns:

False if the Future was cancelled, True otherwise.

Raises:
RuntimeError: if this method was already called or if set_result()

or set_exception() was called.

class satella.coding.concurrent.futures.InvalidStateError

The operation is not allowed in this state.

class satella.coding.concurrent.futures.ExecutorWrapper(executor: Executor)

A wrapping for Python executors to return Satella futures instead of standard Python ones.

shutdown(wait=True)

Clean-up the resources associated with the Executor.

It is safe to call this method several times. Otherwise, no other methods can be called after this one.

Args:
wait: If True then shutdown will not return until all running

futures have finished executing and the resources used by the executor have been reclaimed.

submit(fn, *args, **kwargs) Future

Submits a callable to be executed with the given arguments.

Schedules the callable to be executed as fn(*args, **kwargs) and returns a Future instance representing the execution of the callable.

Returns:

A Future representing the given call.

3 of the aforementioned modules are also allowed to be imported from satella.coding.concurrent, but that is deprecated! Please import them from satella.coding.concurrent.futures.

satella.coding.concurrent.futures.call_in_future(executor: Executor, function: Callable, *args, **kwargs) Callable[[], Future]

Return a callable, whose calling will schedule function to be executed on a target Executor.

The returned function will accept any number of arguments and keyword arguments, but will simply ignore them.

Parameters:
  • executor – executor to run at

  • function – callable to schedule

  • args – arguments to provide to the callable

  • kwargs – keyword arguments to provide to the callable

Returns:

a callable, calling which will schedule function to run at executor. Calling this callable will return the Future for that function

satella.coding.concurrent.futures.wrap_if(fut: Future | Future) Future

Wrap a future, if it isn’t already wrapped

Parameters:

fut – either a Python Future or a Satella Future

Returns:

a Satella future