|
13 | 13 | from dask.base import normalize_seq |
14 | 14 | else: |
15 | 15 | from dask.tokenize import normalize_seq |
| 16 | +from filelock import FileLock |
16 | 17 | from scipy import sparse |
17 | 18 |
|
18 | 19 | import anndata as ad |
19 | 20 | from anndata.tests.helpers import subset_func # noqa: F401 |
20 | 21 |
|
21 | 22 | if TYPE_CHECKING: |
| 23 | + from collections.abc import Generator |
22 | 24 | from types import EllipsisType |
23 | 25 |
|
24 | 26 |
|
@@ -75,6 +77,39 @@ def equivalent_ellipsis_index( |
75 | 77 | return ellipsis_index_with_equivalent[1] |
76 | 78 |
|
77 | 79 |
|
| 80 | +@pytest.fixture(scope="session") |
| 81 | +def local_cluster_addr( |
| 82 | + tmp_path_factory: pytest.TempPathFactory, worker_id: str |
| 83 | +) -> Generator[str, None, None]: |
| 84 | + # Adapted from https://pytest-xdist.readthedocs.io/en/latest/how-to.html#making-session-scoped-fixtures-execute-only-once |
| 85 | + import dask.distributed as dd |
| 86 | + |
| 87 | + def make_cluster() -> dd.LocalCluster: |
| 88 | + return dd.LocalCluster(n_workers=1, threads_per_worker=1) |
| 89 | + |
| 90 | + if worker_id == "master": |
| 91 | + with make_cluster() as cluster: |
| 92 | + yield cluster.scheduler_address |
| 93 | + return |
| 94 | + |
| 95 | + # get the temp directory shared by all workers |
| 96 | + root_tmp_dir = tmp_path_factory.getbasetemp().parent |
| 97 | + |
| 98 | + fn = root_tmp_dir / "dask_scheduler_address.txt" |
| 99 | + lock = FileLock(str(fn) + ".lock") |
| 100 | + lock.acquire() # can’t use context manager, because we need to release the lock before yielding |
| 101 | + address = fn.read_text() if fn.is_file() else None |
| 102 | + if address: |
| 103 | + lock.release() |
| 104 | + yield address |
| 105 | + return |
| 106 | + |
| 107 | + with make_cluster() as cluster: |
| 108 | + fn.write_text(cluster.scheduler_address) |
| 109 | + lock.release() |
| 110 | + yield cluster.scheduler_address |
| 111 | + |
| 112 | + |
78 | 113 | ##################### |
79 | 114 | # Dask tokenization # |
80 | 115 | ##################### |
|
0 commit comments