Skip to content

Commit b5e26fc

Browse files
d33bsgwaybio
andauthored
Avoid parsl executor contention (#496)
* avoid parsl executor contention * better tests * better docs Co-Authored-By: Gregory Way <gregory.way@gmail.com> --------- Co-authored-by: Gregory Way <gregory.way@gmail.com>
1 parent 5bf4ab6 commit b5e26fc

2 files changed

Lines changed: 20 additions & 9 deletions

File tree

‎cytotable/utils.py‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,18 @@ def _parsl_loaded() -> bool:
9393
def _default_parsl_config():
9494
"""
9595
Return a default Parsl configuration for use with CytoTable.
96+
97+
Only a single executor (HighThroughputExecutor) is included by default.
98+
Use of Parsl's ThreadPoolExecutor may result in unfreed memory within
99+
certain systems because of Apache Arrow's memory allocators, so
100+
_ensure_thread_executor adds it only for workflows -- such as Iceberg
101+
image-crop export -- that specifically require it.
96102
"""
97103
return Config(
98104
executors=[
99105
HighThroughputExecutor(
100106
label="htex_default_for_cytotable",
101107
),
102-
ParslThreadPoolExecutor(
103-
label=CYTOTABLE_THREAD_EXECUTOR_LABEL,
104-
max_threads=4,
105-
),
106108
]
107109
)
108110

‎tests/test_iceberg.py‎

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import pytest
1919
from duckdb import IOException as DuckDBIOException
2020
from parsl.config import Config
21-
from parsl.executors import ThreadPoolExecutor
21+
from parsl.executors import HighThroughputExecutor, ThreadPoolExecutor
2222
from pyarrow import parquet
2323

2424
from cytotable.exceptions import CytoTableException
@@ -82,13 +82,22 @@ def test_ensure_thread_executor_does_not_duplicate():
8282
assert len(matching) == 1
8383

8484

85-
def test_default_parsl_config_includes_thread_executor():
85+
def test_default_parsl_config_has_single_executor():
8686
"""
87-
_default_parsl_config always includes the cytotable thread executor.
87+
_default_parsl_config only includes a single HighThroughputExecutor by
88+
default; _ensure_thread_executor adds the cytotable thread executor
89+
only for workflows that need it (e.g. Iceberg image-crop export).
8890
"""
8991
cfg = _default_parsl_config()
90-
labels = {e.label for e in cfg.executors}
91-
assert CYTOTABLE_THREAD_EXECUTOR_LABEL in labels
92+
assert len(cfg.executors) == 1
93+
default_executor = cfg.executors[0]
94+
assert isinstance(default_executor, HighThroughputExecutor)
95+
assert default_executor.label == "htex_default_for_cytotable"
96+
97+
result = _ensure_thread_executor(cfg)
98+
assert len(result.executors) == 2
99+
assert result.executors[0] is default_executor
100+
assert result.executors[1].label == CYTOTABLE_THREAD_EXECUTOR_LABEL
92101

93102

94103
def test_rewrite_join_sql_for_warehouse():

0 commit comments

Comments
 (0)