- C-1: corrige índice de páginas OCR'd (retorna page_number em vez de position) - C-2: adiciona tratamento para falhas de OCR no cache (não distingue erro de não processado) - Integra paralelização do OCR via subprocessos (parallel.py) - Indexador usa extração paralela quando disponível - Melhora relatório de progresso com contagem de páginas processadas
60 lines
1.6 KiB
Python
60 lines
1.6 KiB
Python
"""Execução paralela de tarefas independentes.
|
|
|
|
O gargalo da indexação é o Tesseract, um processo externo. Como o trabalho
|
|
liberado por cada tarefa é predominantemente I/O (subprocesso e escrita em
|
|
disco), threads bastam: o GIL é liberado durante a espera pelo processo.
|
|
|
|
`parallel_map` preserva a ordem dos resultados e isola falhas — uma tarefa que
|
|
lança exceção não derruba as demais.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from concurrent.futures import ThreadPoolExecutor
|
|
from typing import Callable, Iterable, Sequence, TypeVar
|
|
|
|
T = TypeVar("T")
|
|
R = TypeVar("R")
|
|
|
|
|
|
def parallel_map(
|
|
items: Sequence[T],
|
|
function: Callable[[T], R],
|
|
workers: int = 4,
|
|
default: R | None = None,
|
|
) -> list[R | None]:
|
|
"""Aplica `function` a cada item em paralelo, preservando a ordem.
|
|
|
|
Itens cuja função lança exceção recebem o valor `default`.
|
|
"""
|
|
if not items:
|
|
return []
|
|
|
|
worker_count = max(1, min(workers, len(items)))
|
|
|
|
def guarded(item: T) -> R | None:
|
|
try:
|
|
return function(item)
|
|
except Exception:
|
|
return default
|
|
|
|
if worker_count == 1:
|
|
return [guarded(item) for item in items]
|
|
|
|
with ThreadPoolExecutor(max_workers=worker_count) as pool:
|
|
return list(pool.map(guarded, items))
|
|
|
|
|
|
def chunked(items: Iterable[T], size: int) -> list[list[T]]:
|
|
"""Divide um iterável em lotes de tamanho `size`."""
|
|
chunk: list[T] = []
|
|
batches: list[list[T]] = []
|
|
for item in items:
|
|
chunk.append(item)
|
|
if len(chunk) >= size:
|
|
batches.append(chunk)
|
|
chunk = []
|
|
if chunk:
|
|
batches.append(chunk)
|
|
return batches
|