Spaces:
Running
Running
| import logging | |
| from concurrent.futures import ThreadPoolExecutor, as_completed | |
| from tqdm import tqdm | |
| logger = logging.getLogger(__name__) | |
| class ParallelExecutor: | |
| """Standardized wrapper for ThreadPoolExecutor with progress tracking.""" | |
| def __init__(self, max_workers: int = 10): | |
| self.max_workers = max_workers | |
| def map(self, fn, items, desc="Processing", **kwargs): | |
| """Map a function over items in parallel with a progress bar.""" | |
| results = [] | |
| with ThreadPoolExecutor(max_workers=self.max_workers) as executor: | |
| futures = {executor.submit(fn, item): item for item in items} | |
| for future in tqdm(as_completed(futures), total=len(items), desc=desc): | |
| try: | |
| res = future.result() | |
| if res is not None: | |
| results.append(res) | |
| except Exception as e: | |
| logger.error(f"Error processing {futures[future]}: {e}") | |
| return results | |