|
25 | 25 |
|
26 | 26 | from collections.abc import Iterable
|
27 | 27 | from pathlib import Path
|
28 |
| -from typing import Any |
| 28 | +from typing import Any, Optional |
29 | 29 |
|
30 | 30 | import sqlalchemy
|
31 | 31 |
|
@@ -98,15 +98,26 @@ def get_dependent_jobs_recursive(jobs: Iterable[Job]) -> list[Job]:
|
98 | 98 | class JobManager:
|
99 | 99 | """Implements a job manager for Slurm."""
|
100 | 100 |
|
101 |
| - def __init__(self, database: Path, logs_dir: Path) -> None: |
| 101 | + def __init__( |
| 102 | + self, database: Path, logs_dir: Path, read_only: Optional[bool] = None |
| 103 | + ) -> None: |
102 | 104 | self.database = Path(database)
|
| 105 | + # check if database exists and is read-only |
| 106 | + if ( |
| 107 | + read_only is None |
| 108 | + and self.database.exists() |
| 109 | + and not os.access(self.database, os.W_OK) |
| 110 | + ): |
| 111 | + read_only = True |
| 112 | + self.read_only = read_only |
103 | 113 | self.engine = create_engine(f"sqlite:///{self.database}", echo=False)
|
104 | 114 | self.logs_dir = Path(logs_dir)
|
105 | 115 | self.logs_dir.mkdir(exist_ok=True)
|
106 | 116 |
|
107 | 117 | def __enter__(self):
|
108 | 118 | # opens a new session and returns it
|
109 |
| - Base.metadata.create_all(self.engine) |
| 119 | + if not self.read_only: |
| 120 | + Base.metadata.create_all(self.engine) |
110 | 121 | self._session = Session(self.engine)
|
111 | 122 | self._session.begin()
|
112 | 123 | return self._session
|
@@ -165,6 +176,8 @@ def submit_job(self, name, command, array, dependencies):
|
165 | 176 |
|
166 | 177 | def update_jobs(self) -> None:
|
167 | 178 | """Update the status of all jobs."""
|
| 179 | + if self.read_only: |
| 180 | + return |
168 | 181 | jobs_by_grid_id: dict[int, Job] = dict()
|
169 | 182 | query = self.session.query(Job)
|
170 | 183 | for job in query.all():
|
|
0 commit comments