diracx-db 0.0.1a27__py3-none-any.whl → 0.0.1a28__py3-none-any.whl

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.
@@ -7,8 +7,6 @@ from sqlalchemy import delete, func, select, update
7
7
  if TYPE_CHECKING:
8
8
  pass
9
9
 
10
- from diracx.core.properties import JOB_SHARING, SecurityProperty
11
-
12
10
  from ..utils import BaseSQLDB
13
11
  from .schema import (
14
12
  BannedSitesQueue,
@@ -49,126 +47,23 @@ class TaskQueueDB(BaseSQLDB):
49
47
  )
50
48
  return dict((await self.conn.execute(stmt)).one()._mapping)
51
49
 
52
- async def remove_job(self, job_id: int):
53
- """Remove a job from the task queues."""
54
- stmt = delete(JobsQueue).where(JobsQueue.JobId == job_id)
55
- await self.conn.execute(stmt)
56
-
57
- async def remove_jobs(self, job_ids: list[int]):
58
- """Remove jobs from the task queues."""
59
- stmt = delete(JobsQueue).where(JobsQueue.JobId.in_(job_ids))
60
- await self.conn.execute(stmt)
61
-
62
- async def delete_task_queue_if_empty(
63
- self,
64
- tq_id: int,
65
- tq_owner: str,
66
- tq_group: str,
67
- job_share: int,
68
- group_properties: set[SecurityProperty],
69
- enable_shares_correction: bool,
70
- allow_background_tqs: bool,
71
- ):
72
- """Try to delete a task queue if it's empty."""
73
- # Check if the task queue is empty
74
- stmt = (
75
- select(TaskQueues.TQId)
76
- .where(TaskQueues.Enabled >= 1)
77
- .where(TaskQueues.TQId == tq_id)
78
- .where(~TaskQueues.TQId.in_(select(JobsQueue.TQId)))
79
- )
80
- rows = await self.conn.execute(stmt)
81
- if not rows.rowcount:
82
- return
83
-
84
- # Deleting the task queue (the other tables will be deleted in cascade)
85
- stmt = delete(TaskQueues).where(TaskQueues.TQId == tq_id)
86
- await self.conn.execute(stmt)
87
-
88
- await self.recalculate_tq_shares_for_entity(
89
- tq_owner,
90
- tq_group,
91
- job_share,
92
- group_properties,
93
- enable_shares_correction,
94
- allow_background_tqs,
95
- )
96
-
97
- async def recalculate_tq_shares_for_entity(
98
- self,
99
- owner: str,
100
- group: str,
101
- job_share: int,
102
- group_properties: set[SecurityProperty],
103
- enable_shares_correction: bool,
104
- allow_background_tqs: bool,
105
- ):
106
- """Recalculate the shares for a user/userGroup combo."""
107
- if JOB_SHARING in group_properties:
108
- # If group has JobSharing just set prio for that entry, user is irrelevant
109
- return await self.__set_priorities_for_entity(
110
- owner, group, job_share, group_properties, allow_background_tqs
111
- )
112
-
50
+ async def get_task_queue_owners_by_group(self, group: str) -> dict[str, int]:
51
+ """Get the owners for a task queue and group."""
113
52
  stmt = (
114
53
  select(TaskQueues.Owner, func.count(TaskQueues.Owner))
115
54
  .where(TaskQueues.OwnerGroup == group)
116
55
  .group_by(TaskQueues.Owner)
117
56
  )
118
57
  rows = await self.conn.execute(stmt)
119
- # make the rows a list of tuples
120
58
  # Get owners in this group and the amount of times they appear
121
59
  # TODO: I guess the rows are already a list of tupes
122
60
  # maybe refactor
123
- data = [(r[0], r[1]) for r in rows if r]
124
- num_owners = len(data)
125
- # If there are no owners do now
126
- if num_owners == 0:
127
- return
128
- # Split the share amongst the number of owners
129
- entities_shares = {row[0]: job_share / num_owners for row in data}
130
-
131
- # TODO: implement the following
132
- # If corrector is enabled let it work it's magic
133
- # if enable_shares_correction:
134
- # entities_shares = await self.__shares_corrector.correct_shares(
135
- # entitiesShares, group=group
136
- # )
137
-
138
- # Keep updating
139
- owners = dict(data)
140
- # IF the user is already known and has more than 1 tq, the rest of the users don't need to be modified
141
- # (The number of owners didn't change)
142
- if owner in owners and owners[owner] > 1:
143
- await self.__set_priorities_for_entity(
144
- owner,
145
- group,
146
- entities_shares[owner],
147
- group_properties,
148
- allow_background_tqs,
149
- )
150
- return
151
- # Oops the number of owners may have changed so we recalculate the prio for all owners in the group
152
- for owner in owners:
153
- await self.__set_priorities_for_entity(
154
- owner,
155
- group,
156
- entities_shares[owner],
157
- group_properties,
158
- allow_background_tqs,
159
- )
160
-
161
- async def __set_priorities_for_entity(
162
- self,
163
- owner: str,
164
- group: str,
165
- share,
166
- properties: set[SecurityProperty],
167
- allow_background_tqs: bool,
168
- ):
169
- """Set the priority for a user/userGroup combo given a splitted share."""
170
- from DIRAC.WorkloadManagementSystem.DB.TaskQueueDB import calculate_priority
61
+ return {r[0]: r[1] for r in rows if r}
171
62
 
63
+ async def get_task_queue_priorities(
64
+ self, group: str, owner: str | None = None
65
+ ) -> dict[int, float]:
66
+ """Get the priorities for a list of task queues."""
172
67
  stmt = (
173
68
  select(
174
69
  TaskQueues.TQId,
@@ -178,24 +73,48 @@ class TaskQueueDB(BaseSQLDB):
178
73
  .where(TaskQueues.OwnerGroup == group)
179
74
  .group_by(TaskQueues.TQId)
180
75
  )
181
- if JOB_SHARING not in properties:
76
+ if owner:
182
77
  stmt = stmt.where(TaskQueues.Owner == owner)
183
78
  rows = await self.conn.execute(stmt)
184
- tq_dict: dict[int, float] = {tq_id: priority for tq_id, priority in rows}
79
+ return {tq_id: priority for tq_id, priority in rows}
185
80
 
186
- if not tq_dict:
187
- return
81
+ async def remove_jobs(self, job_ids: list[int]):
82
+ """Remove jobs from the task queues."""
83
+ stmt = delete(JobsQueue).where(JobsQueue.JobId.in_(job_ids))
84
+ await self.conn.execute(stmt)
188
85
 
189
- rows = await self.retrieve_task_queues(list(tq_dict))
86
+ async def is_task_queue_empty(self, tq_id: int) -> bool:
87
+ """Check if a task queue is empty."""
88
+ stmt = (
89
+ select(TaskQueues.TQId)
90
+ .where(TaskQueues.Enabled >= 1)
91
+ .where(TaskQueues.TQId == tq_id)
92
+ .where(~TaskQueues.TQId.in_(select(JobsQueue.TQId)))
93
+ )
94
+ rows = await self.conn.execute(stmt)
95
+ return not rows.rowcount
190
96
 
191
- prio_dict = calculate_priority(tq_dict, rows, share, allow_background_tqs)
97
+ async def delete_task_queue(
98
+ self,
99
+ tq_id: int,
100
+ ):
101
+ """Delete a task queue."""
102
+ # Deleting the task queue (the other tables will be deleted in cascade)
103
+ stmt = delete(TaskQueues).where(TaskQueues.TQId == tq_id)
104
+ await self.conn.execute(stmt)
192
105
 
193
- # Execute updates
194
- for prio, tqs in prio_dict.items():
195
- update_stmt = (
196
- update(TaskQueues).where(TaskQueues.TQId.in_(tqs)).values(Priority=prio)
197
- )
198
- await self.conn.execute(update_stmt)
106
+ async def set_priorities_for_entity(
107
+ self,
108
+ tq_ids: list[int],
109
+ priority: float,
110
+ ):
111
+ """Set the priority for a user/userGroup combo given a splitted share."""
112
+ update_stmt = (
113
+ update(TaskQueues)
114
+ .where(TaskQueues.TQId.in_(tq_ids))
115
+ .values(Priority=priority)
116
+ )
117
+ await self.conn.execute(update_stmt)
199
118
 
200
119
  async def retrieve_task_queues(self, tq_id_list=None):
201
120
  """Get all the task queues."""
@@ -6,7 +6,7 @@ from .base import (
6
6
  apply_search_filters,
7
7
  apply_sort_constraints,
8
8
  )
9
- from .functions import substract_date, utcnow
9
+ from .functions import hash, substract_date, utcnow
10
10
  from .types import Column, DateNowColumn, EnumBackedBool, EnumColumn, NullColumn
11
11
 
12
12
  __all__ = (
@@ -20,5 +20,6 @@ __all__ = (
20
20
  "apply_search_filters",
21
21
  "apply_sort_constraints",
22
22
  "substract_date",
23
+ "hash",
23
24
  "SQLDBUnavailableError",
24
25
  )
@@ -104,7 +104,7 @@ class BaseSQLDB(metaclass=ABCMeta):
104
104
  db_classes: list[type[BaseSQLDB]] = [
105
105
  entry_point.load()
106
106
  for entry_point in select_from_extension(
107
- group="diracx.db.sql", name=db_name
107
+ group="diracx.dbs.sql", name=db_name
108
108
  )
109
109
  ]
110
110
  if not db_classes:
@@ -119,7 +119,7 @@ class BaseSQLDB(metaclass=ABCMeta):
119
119
  prefixed with ``DIRACX_DB_URL_{DB_NAME}``.
120
120
  """
121
121
  db_urls: dict[str, str] = {}
122
- for entry_point in select_from_extension(group="diracx.db.sql"):
122
+ for entry_point in select_from_extension(group="diracx.dbs.sql"):
123
123
  db_name = entry_point.name
124
124
  var_name = f"DIRACX_DB_URL_{entry_point.name.upper()}"
125
125
  if var_name in os.environ:
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import hashlib
3
4
  from datetime import datetime, timedelta, timezone
4
5
  from typing import TYPE_CHECKING
5
6
 
@@ -104,3 +105,7 @@ def sqlite_date_trunc(element, compiler, **kw):
104
105
 
105
106
  def substract_date(**kwargs: float) -> datetime:
106
107
  return datetime.now(tz=timezone.utc) - timedelta(**kwargs)
108
+
109
+
110
+ def hash(code: str):
111
+ return hashlib.sha256(code.encode()).hexdigest()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: diracx-db
3
- Version: 0.0.1a27
3
+ Version: 0.0.1a28
4
4
  Summary: TODO
5
5
  License: GPL-3.0-only
6
6
  Classifier: Intended Audience :: Science/Research
@@ -10,9 +10,7 @@ Classifier: Topic :: Scientific/Engineering
10
10
  Classifier: Topic :: System :: Distributed Computing
11
11
  Requires-Python: >=3.11
12
12
  Description-Content-Type: text/markdown
13
- Requires-Dist: dirac
14
13
  Requires-Dist: diracx-core
15
- Requires-Dist: fastapi
16
14
  Requires-Dist: opensearch-py[async]
17
15
  Requires-Dist: pydantic>=2.10
18
16
  Requires-Dist: sqlalchemy[aiomysql,aiosqlite]>=2
@@ -4,36 +4,35 @@ diracx/db/exceptions.py,sha256=1nn-SZLG-nQwkxbvHjZqXhE5ouzWj1f3qhSda2B4ZEg,83
4
4
  diracx/db/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  diracx/db/os/__init__.py,sha256=IZr6z6SefrRvuC8sTC4RmB3_wwOyEt1GzpDuwSMH8O4,112
6
6
  diracx/db/os/job_parameters.py,sha256=Knca19uT2G-5FI7MOFlaOAXeHn4ecPVLIH30TiwhaTw,858
7
- diracx/db/os/utils.py,sha256=k4EBCDLzx_P35aTOoFFrYjO7bnyIF_-PRZGlpMk3IAI,11366
7
+ diracx/db/os/utils.py,sha256=xQLhOgC9YidfeEIbmdigXg3_YZLKHwMcZzhHf4mRwyQ,11399
8
8
  diracx/db/sql/__init__.py,sha256=JYu0b0IVhoXy3lX2m2r2dmAjsRS7IbECBUMEDvX0Te4,391
9
9
  diracx/db/sql/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- diracx/db/sql/auth/db.py,sha256=Ma3P6m49wUNM9wcQZWoQu1CsyJF8vvGeirBFuQUaAIY,10202
10
+ diracx/db/sql/auth/db.py,sha256=O9sp-AKobQ4X4IF2WaJKig-8LU8Ra9Syn5jW8JNLRU4,9030
11
11
  diracx/db/sql/auth/schema.py,sha256=-yXVfNz45W3VvvrNf-ZrSzIgb9qMaI9x1fWDshSkpPU,3141
12
12
  diracx/db/sql/dummy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  diracx/db/sql/dummy/db.py,sha256=whcF02IjFQTwe1l4iTHtCkg2XukEaLHpLeHYNGMuGGw,1645
14
14
  diracx/db/sql/dummy/schema.py,sha256=9zI53pKlzc6qBezsyjkatOQrNZdGCjwgjQ8Iz_pyAXs,789
15
15
  diracx/db/sql/job/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- diracx/db/sql/job/db.py,sha256=21J5vvIT6z_kdVxmoQjiZ61pjCvAXJ5tKN25eJyNR6Q,11712
16
+ diracx/db/sql/job/db.py,sha256=qoK1toWekRP1BO5XbT9CaRuGKR9_oixMVfRZ9myZsjg,8644
17
17
  diracx/db/sql/job/schema.py,sha256=Rmt5ldVN6Pf4MJHMhiT_Zn-k9LVPBTVivmGlyPKFRZE,4647
18
18
  diracx/db/sql/job_logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- diracx/db/sql/job_logging/db.py,sha256=-i_azE67MI95LnXER31USCKioq0l4Q3VJb1oQPdy2Ds,7827
19
+ diracx/db/sql/job_logging/db.py,sha256=0WuRn3pKEeuV9IZ_3VDhlvqI9eM1W4C0dZwIVZKW9N8,5811
20
20
  diracx/db/sql/job_logging/schema.py,sha256=DyFr_4goxfC453xPJX4OkxTGHtlP_5q8PXpr8bhNQS0,960
21
21
  diracx/db/sql/pilot_agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  diracx/db/sql/pilot_agents/db.py,sha256=7-cuCbh_KhM0jlybsHMWV-W66bHsPHIVBpbuqwjncj0,1232
23
23
  diracx/db/sql/pilot_agents/schema.py,sha256=KeWnFSpYOTrT3-_rOCFjbjNnPNXKnUZiJVsu4vv5U2U,2149
24
24
  diracx/db/sql/sandbox_metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- diracx/db/sql/sandbox_metadata/db.py,sha256=7dmWhrg2hD_XDgD2uA9Iao4ZvVvuoEHVGseDwhDuJFc,6817
25
+ diracx/db/sql/sandbox_metadata/db.py,sha256=IyQtTIxRzRv0cdhR3Of1uVzliggePY67bz_9HeKIOjE,6666
26
26
  diracx/db/sql/sandbox_metadata/schema.py,sha256=mI-YpH6NneOQ6QiqwIwyJ4afwfoamybSlQpvaISFfPY,1431
27
27
  diracx/db/sql/task_queue/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- diracx/db/sql/task_queue/db.py,sha256=xY8yPpCIwTC5epcyFGxAP8K9sOVybYsgoH2_QH3NHb8,9105
28
+ diracx/db/sql/task_queue/db.py,sha256=Ymd9cBasiSAPmgu5846B8KmguRiJ_GoJhuOev9YwW2o,6248
29
29
  diracx/db/sql/task_queue/schema.py,sha256=5efAgvNYRkLlaJ2NzRInRfmVa3tyIzQu2l0oRPy4Kzw,3258
30
- diracx/db/sql/utils/__init__.py,sha256=b4lLIYRFVX8PW15ekklzs5OeulA6lNEOfBOJqgIOtYY,529
31
- diracx/db/sql/utils/base.py,sha256=JPT4EdZJ4VQ57kOIbtxD549wbCwVBC-dZ1XLmE9U_4s,12365
32
- diracx/db/sql/utils/functions.py,sha256=2gNckXXpMBcFVIC4Liu-QUmZpBhfrMDUsEi2BIO2tV0,2964
33
- diracx/db/sql/utils/job.py,sha256=U_y8DZdMGU5NbQF3udA4Yg43HaKhF8YhYa-PhzYmIyI,19592
30
+ diracx/db/sql/utils/__init__.py,sha256=QkvpqBuIAgkAOywAssYzdxSzUQVZlSUumK7mPxotXfM,547
31
+ diracx/db/sql/utils/base.py,sha256=7UxHBNLOSjdrIdslMKW4C_c5H9-6Y1BEimxscri2poE,12367
32
+ diracx/db/sql/utils/functions.py,sha256=iLqlUIQ6SrDUtDEnZ5szaFbdcINJW15KNbCdGXss6kc,3055
34
33
  diracx/db/sql/utils/types.py,sha256=yU-tXsu6hFGPsr9ba1n3ZjGPnHQI_06lbpkTeDCWJtg,1287
35
- diracx_db-0.0.1a27.dist-info/METADATA,sha256=6I2J10z8F9OB_vuvT5eMhZ1_cQB6WnNFUyLTwvrdBko,688
36
- diracx_db-0.0.1a27.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
37
- diracx_db-0.0.1a27.dist-info/entry_points.txt,sha256=YLI4f6640bri8Ud6Jt9WNq79pSTVQAkfUasb9f75fR8,315
38
- diracx_db-0.0.1a27.dist-info/top_level.txt,sha256=vJx10tdRlBX3rF2Psgk5jlwVGZNcL3m_7iQWwgPXt-U,7
39
- diracx_db-0.0.1a27.dist-info/RECORD,,
34
+ diracx_db-0.0.1a28.dist-info/METADATA,sha256=7tBHb4St4d0QeFQEBqfMYGTxhXaIOP2K2evK0GvJHCo,644
35
+ diracx_db-0.0.1a28.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
36
+ diracx_db-0.0.1a28.dist-info/entry_points.txt,sha256=UPqhLvb9gui0kOyWeI_edtefcrHToZmQt1p76vIwujo,317
37
+ diracx_db-0.0.1a28.dist-info/top_level.txt,sha256=vJx10tdRlBX3rF2Psgk5jlwVGZNcL3m_7iQWwgPXt-U,7
38
+ diracx_db-0.0.1a28.dist-info/RECORD,,
@@ -1,7 +1,7 @@
1
- [diracx.db.os]
1
+ [diracx.dbs.os]
2
2
  JobParametersDB = diracx.db.os:JobParametersDB
3
3
 
4
- [diracx.db.sql]
4
+ [diracx.dbs.sql]
5
5
  AuthDB = diracx.db.sql:AuthDB
6
6
  JobDB = diracx.db.sql:JobDB
7
7
  JobLoggingDB = diracx.db.sql:JobLoggingDB