@@ -91,6 +91,7 @@ def execute_tasks_h5(
9191 process_dict : dict = {}
9292 cache_dir_dict : dict = {}
9393 file_name_dict : dict = {}
94+ duplicate_dict : dict = {}
9495 while True :
9596 task_dict = None
9697 with contextlib .suppress (queue .Empty ):
@@ -101,6 +102,7 @@ def execute_tasks_h5(
101102 cancel_futures = task_dict .get ("cancel_futures" , False ),
102103 memory_dict = memory_dict ,
103104 process_dict = process_dict ,
105+ duplicate_dict = duplicate_dict ,
104106 cache_dir_dict = cache_dir_dict ,
105107 terminate_function = terminate_function ,
106108 pysqa_config_directory = pysqa_config_directory ,
@@ -175,12 +177,17 @@ def execute_tasks_h5(
175177 process_dict [task_key ] = queue_id
176178 memory_dict [task_key ] = task_dict ["future" ]
177179 cache_dir_dict [task_key ] = cache_directory
180+ elif memory_dict [task_key ] != task_dict ["future" ]:
181+ if task_key not in duplicate_dict :
182+ duplicate_dict [task_key ] = []
183+ duplicate_dict [task_key ].append (task_dict ["future" ])
178184 future_queue .task_done ()
179185 else :
180186 memory_dict = _refresh_memory_dict (
181187 memory_dict = memory_dict ,
182188 cache_dir_dict = cache_dir_dict ,
183189 process_dict = process_dict ,
190+ duplicate_dict = duplicate_dict ,
184191 terminate_function = terminate_function ,
185192 pysqa_config_directory = pysqa_config_directory ,
186193 backend = backend ,
@@ -189,7 +196,7 @@ def execute_tasks_h5(
189196
190197
191198def _check_task_output (
192- task_key : str , future_obj : Future , cache_directory : str
199+ task_key : str , future_obj : Future , cache_directory : str , duplicate_dict : dict
193200) -> Future :
194201 """
195202 Check the output of a task and set the result of the future object if available.
@@ -198,7 +205,7 @@ def _check_task_output(
198205 task_key (str): The key of the task.
199206 future_obj (Future): The future object associated with the task.
200207 cache_directory (str): The directory where the HDF5 files are stored.
201-
208+ duplicate_dict (dict): The dictionary mapping task keys to their associated duplicate future objects.
202209 Returns:
203210 Future: The updated future object.
204211
@@ -211,6 +218,13 @@ def _check_task_output(
211218 future_obj .set_result (result )
212219 elif exec_flag :
213220 future_obj .set_exception (result )
221+ if task_key in duplicate_dict :
222+ for duplicate_future in duplicate_dict [task_key ]:
223+ if exec_flag and no_error_flag :
224+ duplicate_future .set_result (result )
225+ elif exec_flag :
226+ duplicate_future .set_exception (result )
227+ del duplicate_dict [task_key ]
214228 return future_obj
215229
216230
@@ -281,6 +295,7 @@ def _refresh_memory_dict(
281295 memory_dict : dict ,
282296 cache_dir_dict : dict ,
283297 process_dict : dict ,
298+ duplicate_dict : dict ,
284299 terminate_function : Optional [Callable ] = None ,
285300 pysqa_config_directory : Optional [str ] = None ,
286301 backend : Optional [str ] = None ,
@@ -293,6 +308,7 @@ def _refresh_memory_dict(
293308 memory_dict (dict): dictionary with task keys and future objects
294309 cache_dir_dict (dict): dictionary with task keys and cache directories
295310 process_dict (dict): dictionary with task keys and process reference.
311+ duplicate_dict (dict): dictionary with task keys and duplicate future objects.
296312 terminate_function (callable): The function to terminate the tasks.
297313 pysqa_config_directory (str): path to the pysqa config directory (only for pysqa based backend).
298314 backend (str): name of the backend used to spawn tasks.
@@ -315,6 +331,7 @@ def _refresh_memory_dict(
315331 task_key = key ,
316332 future_obj = value ,
317333 cache_directory = cache_dir_dict [key ],
334+ duplicate_dict = duplicate_dict ,
318335 )
319336 for key , value in memory_dict .items ()
320337 if not value .done ()
@@ -399,6 +416,7 @@ def _shutdown_executor(
399416 cancel_futures : bool ,
400417 memory_dict : dict ,
401418 process_dict : dict ,
419+ duplicate_dict : dict ,
402420 cache_dir_dict : dict ,
403421 terminate_function : Optional [Callable ] = None ,
404422 pysqa_config_directory : Optional [str ] = None ,
@@ -421,6 +439,7 @@ def _shutdown_executor(
421439 cancel_futures (bool): Whether to cancel futures that have not yet started.
422440 memory_dict (dict): Mapping of task keys to their Future objects.
423441 process_dict (dict): Mapping of task keys to process handles or queue IDs.
442+ duplicate_dict (dict): Mapping of task keys to lists of duplicate Future objects.
424443 cache_dir_dict (dict): Mapping of task keys to the cache directory for each task.
425444 terminate_function (Callable, optional): Function used to terminate running processes.
426445 pysqa_config_directory (str, optional): Path to the pysqa config directory.
@@ -433,6 +452,7 @@ def _shutdown_executor(
433452 memory_dict = memory_dict ,
434453 cache_dir_dict = cache_dir_dict ,
435454 process_dict = process_dict ,
455+ duplicate_dict = duplicate_dict ,
436456 terminate_function = terminate_function ,
437457 pysqa_config_directory = pysqa_config_directory ,
438458 backend = backend ,
@@ -447,6 +467,7 @@ def _shutdown_executor(
447467 memory_dict = memory_dict ,
448468 cache_dir_dict = cache_dir_dict ,
449469 process_dict = process_dict ,
470+ duplicate_dict = duplicate_dict ,
450471 terminate_function = terminate_function ,
451472 pysqa_config_directory = pysqa_config_directory ,
452473 backend = backend ,
@@ -465,6 +486,7 @@ def _shutdown_executor(
465486 memory_dict = memory_dict ,
466487 cache_dir_dict = cache_dir_dict ,
467488 process_dict = process_dict ,
489+ duplicate_dict = duplicate_dict ,
468490 terminate_function = terminate_function ,
469491 pysqa_config_directory = pysqa_config_directory ,
470492 backend = backend ,
0 commit comments