Futurist
Futurist is a Python library from OpenStack that provides useful additions to `concurrent.futures`, aiming to offer enhanced transparency in asynchronous work execution. It includes features like statistics gathering for executors, an eventlet executor, a synchronous executor, and more. Currently at version 3.3.0, it is actively maintained with a regular release cadence.
Warnings
- gotcha Do not confuse `futurist` (from OpenStack, extending `concurrent.futures`) with `python-future` (a compatibility library for Python 2/3). They serve entirely different purposes, and their usage patterns are distinct. Searching for 'futurist quickstart' may sometimes lead to `python-future` documentation, which is incorrect for this library.
- gotcha The `futurist.ThreadPoolExecutor` (like `concurrent.futures.ThreadPoolExecutor`) does not shrink its thread pool once it has expanded. The pool will eventually reach its `max_workers` capacity and remain at that size for its lifetime, which can lead to higher memory consumption if many temporary workers are created.
- gotcha When using `futurist.ProcessPoolExecutor`, be aware of limitations inherited from `concurrent.futures.ProcessPoolExecutor`, particularly on Windows. Processes cannot be spawned directly if a main module has importable code (e.g., global statements outside of an `if __name__ == '__main__':` block).
Install
-
pip install futurist
Imports
- ThreadPoolExecutor
from futurist import ThreadPoolExecutor
- ProcessPoolExecutor
from futurist import ProcessPoolExecutor
- ExecutorStatistics
from futurist.ext.futures import ExecutorStatistics
Quickstart
import time
from futurist import ThreadPoolExecutor
def my_task(value):
"""A simple task to demonstrate execution and statistics."""
time.sleep(0.01) # Simulate some work
return value * 2
if __name__ == "__main__":
# Initialize ThreadPoolExecutor with a maximum of 2 workers
with ThreadPoolExecutor(max_workers=2) as executor:
print("Submitting tasks...")
# Submit 5 tasks to the executor
futures = [executor.submit(my_task, i) for i in range(5)]
# Retrieve results from completed futures
results = [f.result() for f in futures]
print(f"Results: {results}")
# Access and print execution statistics
stats = executor.statistics
print(f"Executed tasks: {stats.executed}")
print(f"Failed tasks: {stats.failures}")
print(f"Cancelled tasks: {stats.cancelled}")
print(f"Total runtime: {stats.runtime:.4f}s")