diracx-db 0.0.1a32__tar.gz → 0.0.1a34__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/PKG-INFO +1 -1
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/job/db.py +72 -6
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx_db.egg-info/PKG-INFO +1 -1
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/README.md +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/pyproject.toml +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/setup.cfg +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/__init__.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/__main__.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/exceptions.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/os/__init__.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/os/job_parameters.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/os/utils.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/py.typed +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/__init__.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/auth/__init__.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/auth/db.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/auth/schema.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/dummy/__init__.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/dummy/db.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/dummy/schema.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/job/__init__.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/job/schema.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/job_logging/__init__.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/job_logging/db.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/job_logging/schema.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/pilot_agents/__init__.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/pilot_agents/db.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/pilot_agents/schema.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/sandbox_metadata/__init__.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/sandbox_metadata/db.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/sandbox_metadata/schema.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/task_queue/__init__.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/task_queue/db.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/task_queue/schema.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/utils/__init__.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/utils/base.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/utils/functions.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx/db/sql/utils/types.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx_db.egg-info/SOURCES.txt +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx_db.egg-info/dependency_links.txt +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx_db.egg-info/entry_points.txt +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx_db.egg-info/requires.txt +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/src/diracx_db.egg-info/top_level.txt +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/tests/auth/test_authorization_flow.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/tests/auth/test_device_flow.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/tests/auth/test_refresh_token.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/tests/jobs/test_job_db.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/tests/jobs/test_job_logging_db.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/tests/jobs/test_sandbox_metadata.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/tests/opensearch/test_connection.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/tests/opensearch/test_index_template.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/tests/opensearch/test_search.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/tests/pilot_agents/__init__.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/tests/pilot_agents/test_pilot_agents_db.py +0 -0
- {diracx_db-0.0.1a32 → diracx_db-0.0.1a34}/tests/test_dummy_db.py +0 -0
@@ -1,7 +1,9 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
__all__ = ["JobDB"]
|
4
|
+
|
3
5
|
from datetime import datetime, timezone
|
4
|
-
from typing import TYPE_CHECKING, Any
|
6
|
+
from typing import TYPE_CHECKING, Any, Iterable
|
5
7
|
|
6
8
|
from sqlalchemy import bindparam, case, delete, func, insert, select, update
|
7
9
|
|
@@ -9,13 +11,12 @@ if TYPE_CHECKING:
|
|
9
11
|
from sqlalchemy.sql.elements import BindParameter
|
10
12
|
|
11
13
|
from diracx.core.exceptions import InvalidQueryError
|
12
|
-
from diracx.core.models import
|
13
|
-
SearchSpec,
|
14
|
-
SortSpec,
|
15
|
-
)
|
14
|
+
from diracx.core.models import JobCommand, SearchSpec, SortSpec
|
16
15
|
|
17
16
|
from ..utils import BaseSQLDB, apply_search_filters, apply_sort_constraints
|
17
|
+
from ..utils.functions import utcnow
|
18
18
|
from .schema import (
|
19
|
+
HeartBeatLoggingInfo,
|
19
20
|
InputData,
|
20
21
|
JobCommands,
|
21
22
|
JobDBBase,
|
@@ -38,6 +39,16 @@ def _get_columns(table, parameters):
|
|
38
39
|
class JobDB(BaseSQLDB):
|
39
40
|
metadata = JobDBBase.metadata
|
40
41
|
|
42
|
+
# Field names which should be stored in the HeartBeatLoggingInfo table
|
43
|
+
heartbeat_fields = {
|
44
|
+
"LoadAverage",
|
45
|
+
"MemoryUsed",
|
46
|
+
"Vsize",
|
47
|
+
"AvailableDiskSpace",
|
48
|
+
"CPUConsumed",
|
49
|
+
"WallClockTime",
|
50
|
+
}
|
51
|
+
|
41
52
|
# TODO: this is copied from the DIRAC JobDB
|
42
53
|
# but is overwriten in LHCbDIRAC, so we need
|
43
54
|
# to find a way to make it dynamic
|
@@ -197,7 +208,7 @@ class JobDB(BaseSQLDB):
|
|
197
208
|
|
198
209
|
return {jobid: jdl for jobid, jdl in (await self.conn.execute(stmt)) if jdl}
|
199
210
|
|
200
|
-
async def set_job_commands(self, commands: list[tuple[int, str, str]]):
|
211
|
+
async def set_job_commands(self, commands: list[tuple[int, str, str]]) -> None:
|
201
212
|
"""Store a command to be passed to the job together with the next heart beat."""
|
202
213
|
await self.conn.execute(
|
203
214
|
insert(JobCommands),
|
@@ -246,3 +257,58 @@ class JobDB(BaseSQLDB):
|
|
246
257
|
rows = await self.conn.execute(stmt, update_parameters)
|
247
258
|
|
248
259
|
return rows.rowcount
|
260
|
+
|
261
|
+
async def add_heartbeat_data(
|
262
|
+
self, job_id: int, dynamic_data: dict[str, str]
|
263
|
+
) -> None:
|
264
|
+
"""Add the job's heartbeat data to the database.
|
265
|
+
|
266
|
+
NOTE: This does not update the HeartBeatTime column in the Jobs table.
|
267
|
+
This is instead handled by the `diracx.logic.jobs.status.set_job_statuses`
|
268
|
+
as it involves updating multiple databases.
|
269
|
+
|
270
|
+
:param job_id: the job id
|
271
|
+
:param dynamic_data: mapping of the dynamic data to store,
|
272
|
+
e.g. {"AvailableDiskSpace": 123}
|
273
|
+
"""
|
274
|
+
if extra_fields := set(dynamic_data) - self.heartbeat_fields:
|
275
|
+
raise InvalidQueryError(
|
276
|
+
f"Not allowed to store heartbeat data for: {extra_fields}. "
|
277
|
+
f"Allowed keys are: {self.heartbeat_fields}"
|
278
|
+
)
|
279
|
+
values = [
|
280
|
+
{
|
281
|
+
"JobID": job_id,
|
282
|
+
"Name": key,
|
283
|
+
"Value": value,
|
284
|
+
"HeartBeatTime": utcnow(),
|
285
|
+
}
|
286
|
+
for key, value in dynamic_data.items()
|
287
|
+
]
|
288
|
+
await self.conn.execute(HeartBeatLoggingInfo.__table__.insert().values(values))
|
289
|
+
|
290
|
+
async def get_job_commands(self, job_ids: Iterable[int]) -> list[JobCommand]:
|
291
|
+
"""Get a command to be passed to the job together with the next heartbeat.
|
292
|
+
|
293
|
+
:param job_ids: the job ids
|
294
|
+
:return: mapping of job id to list of commands
|
295
|
+
"""
|
296
|
+
# Get the commands
|
297
|
+
stmt = (
|
298
|
+
select(JobCommands.job_id, JobCommands.command, JobCommands.arguments)
|
299
|
+
.where(JobCommands.job_id.in_(job_ids), JobCommands.status == "Received")
|
300
|
+
.order_by(JobCommands.job_id)
|
301
|
+
)
|
302
|
+
commands = await self.conn.execute(stmt)
|
303
|
+
# Update the status of the commands
|
304
|
+
stmt = (
|
305
|
+
update(JobCommands)
|
306
|
+
.where(JobCommands.job_id.in_(job_ids))
|
307
|
+
.values(Status="Sent")
|
308
|
+
)
|
309
|
+
await self.conn.execute(stmt)
|
310
|
+
# Return the commands grouped by job id
|
311
|
+
return [
|
312
|
+
JobCommand(job_id=cmd.job_id, command=cmd.command, arguments=cmd.arguments)
|
313
|
+
for cmd in commands
|
314
|
+
]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|