great-ai/great_ai/utilities/parallel_map/manage_communication.py
Andras Schmelczer c55eba2077
All checks were successful
Publish documentation / publish (push) Successful in 51s
Check / Test on Python 3.10 (push) Successful in 1m1s
Check / Lint, format & type checks (push) Successful in 1m9s
Check / Test on Python 3.11 (push) Successful in 51s
Check / Test on Python 3.12 (push) Successful in 58s
Check / Test on Python 3.13 (push) Successful in 55s
Add max deps and bump old ones
2026-06-06 22:29:16 +01:00

76 lines
2.4 KiB
Python

import multiprocessing as mp
import queue
import traceback
from typing import Dict, Iterable, List, TypeVar, Union
from ..chunk import chunk
from ..logger.get_logger import get_logger
from .map_result import MapResult
from .worker_exception import WorkerException
logger = get_logger("parallel_map")
T = TypeVar("T")
V = TypeVar("V")
def manage_communication(
*,
input_values: Iterable[T],
chunk_size: int,
input_queue: Union[mp.Queue, queue.Queue],
output_queue: Union[mp.Queue, queue.Queue],
unordered: bool,
ignore_exceptions: bool,
) -> Iterable[V]:
chunks = iter(chunk(enumerate(input_values), chunk_size=chunk_size))
indexed_results: Dict[int, V] = {}
next_output_index = 0
read_input_length = 0
is_iteration_over = False
while not is_iteration_over or next_output_index < read_input_length:
if not is_iteration_over:
try:
next_chunk = next(chunks)
input_queue.put(next_chunk)
read_input_length += len(next_chunk)
except StopIteration:
is_iteration_over = True
except Exception as e:
if ignore_exceptions:
logger.error(
f"""Exception {e} encountered in input, traceback:\n{
traceback.format_exc()
}"""
)
else:
raise
try:
result_chunk: List[MapResult] = output_queue.get_nowait()
for r in result_chunk:
if r.exception is not None:
if ignore_exceptions:
logger.error(
f"""Exception {
r.exception
} encountered in worker, traceback:\n{r.worker_traceback}"""
)
else:
raise WorkerException(r.exception)
if unordered:
yield r.value
next_output_index += 1
else:
indexed_results[r.order] = r.value
if not unordered:
while next_output_index in indexed_results:
yield indexed_results[next_output_index]
del indexed_results[next_output_index]
next_output_index += 1
except queue.Empty:
pass