diracx-db 0.0.1a33__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.
Files changed (55) hide show
  1. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/PKG-INFO +1 -1
  2. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/job/db.py +72 -6
  3. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx_db.egg-info/PKG-INFO +1 -1
  4. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/README.md +0 -0
  5. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/pyproject.toml +0 -0
  6. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/setup.cfg +0 -0
  7. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/__init__.py +0 -0
  8. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/__main__.py +0 -0
  9. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/exceptions.py +0 -0
  10. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/os/__init__.py +0 -0
  11. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/os/job_parameters.py +0 -0
  12. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/os/utils.py +0 -0
  13. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/py.typed +0 -0
  14. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/__init__.py +0 -0
  15. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/auth/__init__.py +0 -0
  16. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/auth/db.py +0 -0
  17. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/auth/schema.py +0 -0
  18. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/dummy/__init__.py +0 -0
  19. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/dummy/db.py +0 -0
  20. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/dummy/schema.py +0 -0
  21. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/job/__init__.py +0 -0
  22. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/job/schema.py +0 -0
  23. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/job_logging/__init__.py +0 -0
  24. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/job_logging/db.py +0 -0
  25. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/job_logging/schema.py +0 -0
  26. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/pilot_agents/__init__.py +0 -0
  27. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/pilot_agents/db.py +0 -0
  28. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/pilot_agents/schema.py +0 -0
  29. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/sandbox_metadata/__init__.py +0 -0
  30. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/sandbox_metadata/db.py +0 -0
  31. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/sandbox_metadata/schema.py +0 -0
  32. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/task_queue/__init__.py +0 -0
  33. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/task_queue/db.py +0 -0
  34. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/task_queue/schema.py +0 -0
  35. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/utils/__init__.py +0 -0
  36. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/utils/base.py +0 -0
  37. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/utils/functions.py +0 -0
  38. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx/db/sql/utils/types.py +0 -0
  39. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx_db.egg-info/SOURCES.txt +0 -0
  40. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx_db.egg-info/dependency_links.txt +0 -0
  41. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx_db.egg-info/entry_points.txt +0 -0
  42. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx_db.egg-info/requires.txt +0 -0
  43. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/src/diracx_db.egg-info/top_level.txt +0 -0
  44. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/tests/auth/test_authorization_flow.py +0 -0
  45. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/tests/auth/test_device_flow.py +0 -0
  46. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/tests/auth/test_refresh_token.py +0 -0
  47. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/tests/jobs/test_job_db.py +0 -0
  48. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/tests/jobs/test_job_logging_db.py +0 -0
  49. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/tests/jobs/test_sandbox_metadata.py +0 -0
  50. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/tests/opensearch/test_connection.py +0 -0
  51. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/tests/opensearch/test_index_template.py +0 -0
  52. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/tests/opensearch/test_search.py +0 -0
  53. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/tests/pilot_agents/__init__.py +0 -0
  54. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/tests/pilot_agents/test_pilot_agents_db.py +0 -0
  55. {diracx_db-0.0.1a33 → diracx_db-0.0.1a34}/tests/test_dummy_db.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diracx-db
3
- Version: 0.0.1a33
3
+ Version: 0.0.1a34
4
4
  Summary: TODO
5
5
  License: GPL-3.0-only
6
6
  Classifier: Intended Audience :: Science/Research
@@ -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
+ ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: diracx-db
3
- Version: 0.0.1a33
3
+ Version: 0.0.1a34
4
4
  Summary: TODO
5
5
  License: GPL-3.0-only
6
6
  Classifier: Intended Audience :: Science/Research
File without changes
File without changes