rucio 35.7.0__py3-none-any.whl → 37.0.0rc2__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.

Potentially problematic release.


This version of rucio might be problematic. Click here for more details.

Files changed (268) hide show
  1. rucio/alembicrevision.py +1 -1
  2. rucio/{daemons/c3po/collectors → cli}/__init__.py +1 -0
  3. rucio/cli/account.py +216 -0
  4. rucio-35.7.0.data/scripts/rucio → rucio/cli/bin_legacy/rucio.py +769 -486
  5. rucio-35.7.0.data/scripts/rucio-admin → rucio/cli/bin_legacy/rucio_admin.py +476 -423
  6. rucio/cli/command.py +272 -0
  7. rucio/cli/config.py +72 -0
  8. rucio/cli/did.py +191 -0
  9. rucio/cli/download.py +128 -0
  10. rucio/cli/lifetime_exception.py +33 -0
  11. rucio/cli/replica.py +162 -0
  12. rucio/cli/rse.py +293 -0
  13. rucio/cli/rule.py +158 -0
  14. rucio/cli/scope.py +40 -0
  15. rucio/cli/subscription.py +73 -0
  16. rucio/cli/upload.py +60 -0
  17. rucio/cli/utils.py +226 -0
  18. rucio/client/accountclient.py +0 -1
  19. rucio/client/baseclient.py +33 -24
  20. rucio/client/client.py +45 -1
  21. rucio/client/didclient.py +5 -3
  22. rucio/client/downloadclient.py +6 -8
  23. rucio/client/replicaclient.py +0 -2
  24. rucio/client/richclient.py +317 -0
  25. rucio/client/rseclient.py +4 -4
  26. rucio/client/uploadclient.py +26 -12
  27. rucio/common/bittorrent.py +234 -0
  28. rucio/common/cache.py +66 -29
  29. rucio/common/checksum.py +168 -0
  30. rucio/common/client.py +122 -0
  31. rucio/common/config.py +22 -35
  32. rucio/common/constants.py +61 -3
  33. rucio/common/didtype.py +72 -24
  34. rucio/common/dumper/__init__.py +45 -38
  35. rucio/common/dumper/consistency.py +75 -30
  36. rucio/common/dumper/data_models.py +63 -19
  37. rucio/common/dumper/path_parsing.py +19 -8
  38. rucio/common/exception.py +65 -8
  39. rucio/common/extra.py +5 -10
  40. rucio/common/logging.py +13 -13
  41. rucio/common/pcache.py +8 -7
  42. rucio/common/plugins.py +59 -27
  43. rucio/common/policy.py +12 -3
  44. rucio/common/schema/__init__.py +84 -34
  45. rucio/common/schema/generic.py +0 -17
  46. rucio/common/schema/generic_multi_vo.py +0 -17
  47. rucio/common/stomp_utils.py +383 -119
  48. rucio/common/test_rucio_server.py +12 -6
  49. rucio/common/types.py +132 -52
  50. rucio/common/utils.py +93 -643
  51. rucio/core/account_limit.py +14 -12
  52. rucio/core/authentication.py +2 -2
  53. rucio/core/config.py +23 -42
  54. rucio/core/credential.py +14 -15
  55. rucio/core/did.py +5 -1
  56. rucio/core/did_meta_plugins/elasticsearch_meta.py +407 -0
  57. rucio/core/did_meta_plugins/filter_engine.py +62 -3
  58. rucio/core/did_meta_plugins/json_meta.py +2 -2
  59. rucio/core/did_meta_plugins/mongo_meta.py +43 -30
  60. rucio/core/did_meta_plugins/postgres_meta.py +75 -39
  61. rucio/core/identity.py +6 -5
  62. rucio/core/importer.py +4 -3
  63. rucio/core/lifetime_exception.py +2 -2
  64. rucio/core/lock.py +8 -7
  65. rucio/core/message.py +6 -0
  66. rucio/core/monitor.py +30 -29
  67. rucio/core/naming_convention.py +2 -2
  68. rucio/core/nongrid_trace.py +2 -2
  69. rucio/core/oidc.py +11 -9
  70. rucio/core/permission/__init__.py +79 -37
  71. rucio/core/permission/generic.py +1 -7
  72. rucio/core/permission/generic_multi_vo.py +1 -7
  73. rucio/core/quarantined_replica.py +4 -3
  74. rucio/core/replica.py +464 -139
  75. rucio/core/replica_sorter.py +55 -59
  76. rucio/core/request.py +34 -32
  77. rucio/core/rse.py +301 -97
  78. rucio/core/rse_counter.py +1 -2
  79. rucio/core/rse_expression_parser.py +7 -7
  80. rucio/core/rse_selector.py +9 -7
  81. rucio/core/rule.py +41 -40
  82. rucio/core/rule_grouping.py +42 -40
  83. rucio/core/scope.py +5 -4
  84. rucio/core/subscription.py +26 -28
  85. rucio/core/topology.py +11 -11
  86. rucio/core/trace.py +2 -2
  87. rucio/core/transfer.py +29 -15
  88. rucio/core/volatile_replica.py +4 -3
  89. rucio/daemons/atropos/atropos.py +1 -1
  90. rucio/daemons/auditor/__init__.py +2 -2
  91. rucio/daemons/auditor/srmdumps.py +6 -6
  92. rucio/daemons/automatix/automatix.py +32 -21
  93. rucio/daemons/badreplicas/necromancer.py +2 -2
  94. rucio/daemons/bb8/nuclei_background_rebalance.py +1 -1
  95. rucio/daemons/bb8/t2_background_rebalance.py +1 -1
  96. rucio/daemons/cache/consumer.py +26 -90
  97. rucio/daemons/common.py +15 -25
  98. rucio/daemons/conveyor/finisher.py +2 -2
  99. rucio/daemons/conveyor/poller.py +18 -28
  100. rucio/daemons/conveyor/receiver.py +53 -123
  101. rucio/daemons/conveyor/stager.py +1 -0
  102. rucio/daemons/conveyor/submitter.py +3 -3
  103. rucio/daemons/hermes/hermes.py +129 -369
  104. rucio/daemons/judge/evaluator.py +2 -2
  105. rucio/daemons/oauthmanager/oauthmanager.py +3 -3
  106. rucio/daemons/reaper/dark_reaper.py +7 -3
  107. rucio/daemons/reaper/reaper.py +12 -16
  108. rucio/daemons/rsedecommissioner/config.py +1 -1
  109. rucio/daemons/rsedecommissioner/profiles/generic.py +5 -4
  110. rucio/daemons/rsedecommissioner/profiles/types.py +7 -6
  111. rucio/daemons/rsedecommissioner/rse_decommissioner.py +1 -1
  112. rucio/daemons/storage/consistency/actions.py +8 -6
  113. rucio/daemons/tracer/kronos.py +117 -142
  114. rucio/db/sqla/constants.py +5 -0
  115. rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +4 -4
  116. rucio/db/sqla/migrate_repo/versions/30d5206e9cad_increase_oauthrequest_redirect_msg_.py +37 -0
  117. rucio/db/sqla/models.py +157 -154
  118. rucio/db/sqla/session.py +58 -27
  119. rucio/db/sqla/types.py +2 -2
  120. rucio/db/sqla/util.py +2 -2
  121. rucio/gateway/account.py +18 -12
  122. rucio/gateway/account_limit.py +137 -60
  123. rucio/gateway/authentication.py +18 -12
  124. rucio/gateway/config.py +30 -20
  125. rucio/gateway/credential.py +9 -10
  126. rucio/gateway/did.py +70 -53
  127. rucio/gateway/dirac.py +6 -4
  128. rucio/gateway/exporter.py +3 -2
  129. rucio/gateway/heartbeat.py +6 -4
  130. rucio/gateway/identity.py +36 -51
  131. rucio/gateway/importer.py +3 -2
  132. rucio/gateway/lifetime_exception.py +3 -2
  133. rucio/gateway/meta_conventions.py +17 -6
  134. rucio/gateway/permission.py +4 -1
  135. rucio/gateway/quarantined_replica.py +3 -2
  136. rucio/gateway/replica.py +31 -22
  137. rucio/gateway/request.py +27 -18
  138. rucio/gateway/rse.py +69 -37
  139. rucio/gateway/rule.py +46 -26
  140. rucio/gateway/scope.py +3 -2
  141. rucio/gateway/subscription.py +14 -11
  142. rucio/gateway/vo.py +12 -8
  143. rucio/rse/__init__.py +3 -3
  144. rucio/rse/protocols/bittorrent.py +11 -1
  145. rucio/rse/protocols/cache.py +0 -11
  146. rucio/rse/protocols/dummy.py +0 -11
  147. rucio/rse/protocols/gfal.py +14 -9
  148. rucio/rse/protocols/globus.py +1 -1
  149. rucio/rse/protocols/http_cache.py +1 -1
  150. rucio/rse/protocols/posix.py +2 -2
  151. rucio/rse/protocols/protocol.py +84 -317
  152. rucio/rse/protocols/rclone.py +2 -1
  153. rucio/rse/protocols/rfio.py +10 -1
  154. rucio/rse/protocols/ssh.py +2 -1
  155. rucio/rse/protocols/storm.py +2 -13
  156. rucio/rse/protocols/webdav.py +74 -30
  157. rucio/rse/protocols/xrootd.py +2 -1
  158. rucio/rse/rsemanager.py +170 -53
  159. rucio/rse/translation.py +260 -0
  160. rucio/tests/common.py +23 -13
  161. rucio/tests/common_server.py +26 -9
  162. rucio/transfertool/bittorrent.py +15 -14
  163. rucio/transfertool/bittorrent_driver.py +5 -7
  164. rucio/transfertool/bittorrent_driver_qbittorrent.py +9 -8
  165. rucio/transfertool/fts3.py +20 -16
  166. rucio/transfertool/mock.py +2 -3
  167. rucio/vcsversion.py +4 -4
  168. rucio/version.py +7 -0
  169. rucio/web/rest/flaskapi/v1/accounts.py +17 -3
  170. rucio/web/rest/flaskapi/v1/auth.py +5 -5
  171. rucio/web/rest/flaskapi/v1/credentials.py +3 -2
  172. rucio/web/rest/flaskapi/v1/dids.py +21 -15
  173. rucio/web/rest/flaskapi/v1/identities.py +33 -9
  174. rucio/web/rest/flaskapi/v1/redirect.py +5 -4
  175. rucio/web/rest/flaskapi/v1/replicas.py +12 -8
  176. rucio/web/rest/flaskapi/v1/rses.py +15 -4
  177. rucio/web/rest/flaskapi/v1/traces.py +56 -19
  178. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/alembic.ini.template +1 -1
  179. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/alembic_offline.ini.template +1 -1
  180. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/rucio.cfg.atlas.client.template +3 -2
  181. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/rucio.cfg.template +3 -19
  182. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/rucio_multi_vo.cfg.template +1 -18
  183. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/requirements.server.txt +97 -68
  184. rucio-37.0.0rc2.data/scripts/rucio +133 -0
  185. rucio-37.0.0rc2.data/scripts/rucio-admin +97 -0
  186. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-atropos +2 -2
  187. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-auditor +2 -1
  188. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-automatix +2 -2
  189. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-cache-client +17 -10
  190. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-receiver +1 -0
  191. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-kronos +1 -0
  192. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-minos +2 -2
  193. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-minos-temporary-expiration +2 -2
  194. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-necromancer +2 -2
  195. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-reaper +6 -6
  196. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-transmogrifier +2 -2
  197. rucio-37.0.0rc2.dist-info/METADATA +92 -0
  198. {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/RECORD +239 -245
  199. {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/licenses/AUTHORS.rst +3 -0
  200. rucio/common/schema/atlas.py +0 -413
  201. rucio/common/schema/belleii.py +0 -408
  202. rucio/common/schema/domatpc.py +0 -401
  203. rucio/common/schema/escape.py +0 -426
  204. rucio/common/schema/icecube.py +0 -406
  205. rucio/core/permission/atlas.py +0 -1348
  206. rucio/core/permission/belleii.py +0 -1077
  207. rucio/core/permission/escape.py +0 -1078
  208. rucio/daemons/c3po/algorithms/__init__.py +0 -13
  209. rucio/daemons/c3po/algorithms/simple.py +0 -134
  210. rucio/daemons/c3po/algorithms/t2_free_space.py +0 -128
  211. rucio/daemons/c3po/algorithms/t2_free_space_only_pop.py +0 -130
  212. rucio/daemons/c3po/algorithms/t2_free_space_only_pop_with_network.py +0 -294
  213. rucio/daemons/c3po/c3po.py +0 -371
  214. rucio/daemons/c3po/collectors/agis.py +0 -108
  215. rucio/daemons/c3po/collectors/free_space.py +0 -81
  216. rucio/daemons/c3po/collectors/jedi_did.py +0 -57
  217. rucio/daemons/c3po/collectors/mock_did.py +0 -51
  218. rucio/daemons/c3po/collectors/network_metrics.py +0 -71
  219. rucio/daemons/c3po/collectors/workload.py +0 -112
  220. rucio/daemons/c3po/utils/__init__.py +0 -13
  221. rucio/daemons/c3po/utils/dataset_cache.py +0 -50
  222. rucio/daemons/c3po/utils/expiring_dataset_cache.py +0 -56
  223. rucio/daemons/c3po/utils/expiring_list.py +0 -62
  224. rucio/daemons/c3po/utils/popularity.py +0 -85
  225. rucio/daemons/c3po/utils/timeseries.py +0 -89
  226. rucio/rse/protocols/gsiftp.py +0 -92
  227. rucio-35.7.0.data/scripts/rucio-c3po +0 -85
  228. rucio-35.7.0.dist-info/METADATA +0 -72
  229. /rucio/{daemons/c3po → cli/bin_legacy}/__init__.py +0 -0
  230. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/globus-config.yml.template +0 -0
  231. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/ldap.cfg.template +0 -0
  232. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
  233. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
  234. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
  235. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
  236. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
  237. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
  238. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
  239. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/tools/bootstrap.py +0 -0
  240. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/tools/merge_rucio_configs.py +0 -0
  241. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/tools/reset_database.py +0 -0
  242. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-abacus-account +0 -0
  243. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-abacus-collection-replica +0 -0
  244. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-abacus-rse +0 -0
  245. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-bb8 +0 -0
  246. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-cache-consumer +0 -0
  247. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-finisher +0 -0
  248. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-poller +0 -0
  249. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-preparer +0 -0
  250. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-stager +0 -0
  251. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-submitter +0 -0
  252. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-throttler +0 -0
  253. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-dark-reaper +0 -0
  254. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-dumper +0 -0
  255. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-follower +0 -0
  256. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-hermes +0 -0
  257. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-judge-cleaner +0 -0
  258. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-judge-evaluator +0 -0
  259. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-judge-injector +0 -0
  260. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-judge-repairer +0 -0
  261. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-oauth-manager +0 -0
  262. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-replica-recoverer +0 -0
  263. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-rse-decommissioner +0 -0
  264. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-storage-consistency-actions +0 -0
  265. {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-undertaker +0 -0
  266. {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/WHEEL +0 -0
  267. {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/licenses/LICENSE +0 -0
  268. {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/top_level.txt +0 -0
@@ -21,13 +21,12 @@ import logging
21
21
  import threading
22
22
  import time
23
23
  from traceback import format_exc
24
- from typing import TYPE_CHECKING, Optional
24
+ from typing import TYPE_CHECKING
25
25
 
26
26
  import rucio.db.sqla.util
27
27
  from rucio.common import exception
28
- from rucio.common.config import config_get, config_get_bool, config_get_int, config_get_list
29
28
  from rucio.common.logging import formatted_logger, setup_logging
30
- from rucio.common.stomp_utils import StompConnectionManager
29
+ from rucio.common.stomp_utils import ListenerBase, StompConnectionManager
31
30
  from rucio.common.types import InternalScope, LoggerFunction
32
31
  from rucio.core.monitor import MetricManager
33
32
  from rucio.core.rse import get_rse_id
@@ -36,7 +35,6 @@ from rucio.core.volatile_replica import add_volatile_replicas, delete_volatile_r
36
35
  if TYPE_CHECKING:
37
36
  from types import FrameType
38
37
 
39
- from stomp import Connection
40
38
  from stomp.utils import Frame
41
39
 
42
40
  logging.getLogger("stomp").setLevel(logging.CRITICAL)
@@ -46,35 +44,11 @@ GRACEFUL_STOP = threading.Event()
46
44
  DAEMON_NAME = 'cache-consumer'
47
45
 
48
46
 
49
- class AMQConsumer:
47
+ class AMQConsumer(ListenerBase):
50
48
  """
51
49
  class Consumer
52
50
  """
53
51
 
54
- def __init__(
55
- self,
56
- broker: str,
57
- conn: "Connection",
58
- logger: "LoggerFunction"
59
- ):
60
- """
61
- __init__
62
- """
63
- self.__broker = broker
64
- self.__conn = conn
65
- self.__logger = logger
66
-
67
- @METRICS.count_it
68
- def on_heartbeat_timeout(self) -> None:
69
- self.__conn.disconnect()
70
-
71
- @METRICS.count_it
72
- def on_error(self, frame: "Frame") -> None:
73
- """
74
- on_error
75
- """
76
- self.__logger(logging.ERROR, 'Message receive error: [%s] %s' % (self.__broker, frame.body))
77
-
78
52
  @METRICS.count_it
79
53
  def on_message(self, frame: "Frame") -> None:
80
54
  """
@@ -82,7 +56,7 @@ class AMQConsumer:
82
56
  """
83
57
  try:
84
58
  msg = json.loads(frame.body) # type: ignore
85
- self.__logger(logging.DEBUG, 'Message received: %s ' % msg)
59
+ self._logger(logging.DEBUG, 'Message received: %s', msg)
86
60
  if isinstance(msg, dict) and 'operation' in msg.keys():
87
61
  for f in msg['files']:
88
62
  f['scope'] = InternalScope(f['scope'])
@@ -93,81 +67,42 @@ class AMQConsumer:
93
67
 
94
68
  rse_vo_str = msg['rse']
95
69
  if 'vo' in msg and msg['vo'] != 'def':
96
- rse_vo_str = '{} on {}'.format(rse_vo_str, msg['vo'])
70
+ rse_vo_str = f"{rse_vo_str} on {msg['vo']}"
97
71
  if msg['operation'] == 'add_replicas':
98
- self.__logger(logging.INFO, 'add_replicas to RSE %s: %s ' % (rse_vo_str, str(msg['files'])))
72
+ self._logger(logging.INFO, "add_replicas to RSE %s: %s", rse_vo_str, str(msg['files']))
99
73
  add_volatile_replicas(rse_id=rse_id, replicas=msg['files'])
100
74
  elif msg['operation'] == 'delete_replicas':
101
- self.__logger(logging.INFO, 'delete_replicas to RSE %s: %s ' % (rse_vo_str, str(msg['files'])))
75
+ self._logger(logging.INFO, "delete_replicas to RSE %s: %s", rse_vo_str, str(msg['files']))
102
76
  delete_volatile_replicas(rse_id=rse_id, replicas=msg['files'])
103
77
  else:
104
- self.__logger(logging.DEBUG, 'Check failed: %s %s '
105
- % (isinstance(msg, dict), 'operation' in msg.keys()))
78
+ self._logger(logging.DEBUG, 'Check failed: %s %s', isinstance(msg, dict), "operation" in msg.keys())
106
79
  except:
107
- self.__logger(logging.ERROR, str(format_exc()))
80
+ self._logger(logging.ERROR, str(format_exc()))
108
81
 
109
82
 
110
- def consumer(id_: int, num_thread: int = 1) -> None:
83
+ def consumer(id_: int, num_thread: int = 1, logger: LoggerFunction = logging.log) -> None:
111
84
  """
112
85
  Main loop to consume messages from the Rucio Cache producer.
113
86
  """
114
-
115
- logger = formatted_logger(logging.log, DAEMON_NAME + ' %s')
116
-
117
87
  logger(logging.INFO, 'Rucio Cache consumer starting')
118
88
 
119
- brokers = config_get_list('messaging-cache', 'brokers')
120
-
121
- use_ssl = config_get_bool('messaging-cache', 'use_ssl', default=True, raise_exception=False)
122
- if not use_ssl:
123
- username = config_get('messaging-cache', 'username')
124
- password = config_get('messaging-cache', 'password')
125
- destination = config_get('messaging-cache', 'destination')
126
- subscription_id = 'rucio-cache-messaging'
127
-
128
- vhost = config_get('messaging-cache', 'broker_virtual_host', raise_exception=False)
129
- port = config_get_int('messaging-cache', 'port')
130
- reconnect_attempts = config_get_int('messaging-cache', 'reconnect_attempts', default=100)
131
- ssl_key_file = config_get('messaging-cache', 'ssl_key_file', raise_exception=False)
132
- ssl_cert_file = config_get('messaging-cache', 'ssl_cert_file', raise_exception=False)
133
-
134
- stomp_conn_mngr = StompConnectionManager()
135
- conns, _ = stomp_conn_mngr.re_configure(
136
- brokers=brokers,
137
- port=port,
138
- use_ssl=use_ssl,
139
- vhost=vhost,
140
- reconnect_attempts=reconnect_attempts,
141
- ssl_key_file=ssl_key_file,
142
- ssl_cert_file=ssl_cert_file,
143
- timeout=None,
144
- logger=logger
145
- )
89
+ conn_mgr = StompConnectionManager(config_section='messaging-cache', logger=logger)
146
90
 
147
91
  logger(logging.INFO, 'consumer started')
148
92
 
93
+ conn_mgr.set_listener_factory('rucio-cache-consumer', AMQConsumer, heartbeats=conn_mgr.config.heartbeats)
94
+
149
95
  while not GRACEFUL_STOP.is_set():
150
- for conn in conns:
151
- if not conn.is_connected():
152
- host_port = conn.transport._Transport__host_and_ports[0]
153
-
154
- logger(logging.INFO, 'connecting to %s' % host_port[0])
155
- METRICS.counter('reconnect.{host}').labels(host=host_port[0]).inc()
156
- conn.set_listener('rucio-cache-consumer', AMQConsumer(broker=host_port, conn=conn, logger=logger))
157
- if not use_ssl:
158
- conn.connect(username, password)
159
- else:
160
- conn.connect()
161
96
 
162
- conn.subscribe(destination=destination, ack='auto', id=subscription_id)
97
+ conn_mgr.subscribe(id_='rucio-cache-messaging', ack='auto')
163
98
  time.sleep(1)
164
99
 
165
100
  logger(logging.INFO, 'graceful stop requested')
166
- stomp_conn_mngr.disconnect()
101
+ conn_mgr.disconnect()
167
102
  logger(logging.INFO, 'graceful stop done')
168
103
 
169
104
 
170
- def stop(signum: Optional[int] = None, frame: Optional["FrameType"] = None) -> None:
105
+ def stop(signum: "int | None" = None, frame: "FrameType | None" = None) -> None:
171
106
  """
172
107
  Graceful exit.
173
108
  """
@@ -180,18 +115,19 @@ def run(num_thread: int = 1) -> None:
180
115
  Starts up the rucio cache consumer thread
181
116
  """
182
117
  setup_logging(process_name=DAEMON_NAME)
118
+ logger = formatted_logger(logging.log, DAEMON_NAME + ' %s')
183
119
 
184
120
  if rucio.db.sqla.util.is_old_db():
185
121
  raise exception.DatabaseException('Database was not updated, daemon won\'t start')
186
122
 
187
- logging.info('starting consumer thread')
188
- threads = [threading.Thread(target=consumer, kwargs={'id_': i, 'num_thread': num_thread})
189
- for i in range(0, num_thread)]
190
-
191
- [t.start() for t in threads]
123
+ logger(logging.INFO, 'starting consumer thread')
124
+ threads = []
125
+ for i in range(num_thread):
126
+ con_thread = threading.Thread(target=consumer, kwargs={'id_': i, 'num_thread': num_thread, 'logger': logger})
127
+ con_thread.start()
128
+ threads.append(con_thread)
192
129
 
193
- logging.info('waiting for interrupts')
130
+ logger(logging.INFO, 'waiting for interrupts')
194
131
 
195
- # Interruptible joins require a timeout.
196
- while threads[0].is_alive():
197
- [t.join(timeout=3.14) for t in threads]
132
+ while [thread.join(timeout=3.14) for thread in threads if thread.is_alive()]:
133
+ pass
rucio/daemons/common.py CHANGED
@@ -20,7 +20,6 @@ import queue
20
20
  import socket
21
21
  import threading
22
22
  import time
23
- from collections.abc import Callable, Generator, Iterator, Sequence
24
23
  from typing import TYPE_CHECKING, Any, Generic, Optional, TypeVar, Union
25
24
 
26
25
  from rucio.common.logging import formatted_logger
@@ -29,6 +28,8 @@ from rucio.core import heartbeat as heartbeat_core
29
28
  from rucio.core.monitor import MetricManager
30
29
 
31
30
  if TYPE_CHECKING:
31
+ from collections.abc import Callable, Generator, Iterator, Sequence
32
+
32
33
  from rucio.common.types import LoggerFunction
33
34
 
34
35
  T = TypeVar('T')
@@ -85,7 +86,7 @@ class HeartbeatHandler:
85
86
  self,
86
87
  force_renew: bool = False,
87
88
  payload: Optional[str] = None
88
- ) -> tuple[int, int, Callable]:
89
+ ) -> tuple[int, int, 'Callable']:
89
90
  """
90
91
  :return: a tuple: <the number of the current worker>, <total number of workers>, <decorated logger>
91
92
  """
@@ -115,9 +116,9 @@ class HeartbeatHandler:
115
116
  def _activity_looper(
116
117
  once: bool,
117
118
  sleep_time: int,
118
- activities: Optional[Sequence[str]],
119
+ activities: Optional['Sequence[str]'],
119
120
  heartbeat_handler: HeartbeatHandler,
120
- ) -> Generator[tuple[str, float], tuple[float, bool], None]:
121
+ ) -> 'Generator[tuple[str, float], tuple[float, bool], None]':
121
122
  """
122
123
  Generator which loops (either once, or indefinitely) over all activities while ensuring that `sleep_time`
123
124
  passes between handling twice the same activity.
@@ -164,7 +165,7 @@ def _activity_looper(
164
165
  if not once:
165
166
  if must_sleep:
166
167
  time_diff = time.time() - actual_exe_time
167
- time_to_sleep = max(1, sleep_time - time_diff)
168
+ time_to_sleep = max(1.0, sleep_time - time_diff)
168
169
  activity_next_exe_time[activity] = time.time() + time_to_sleep
169
170
  else:
170
171
  activity_next_exe_time[activity] = time.time() + 1
@@ -176,19 +177,8 @@ def db_workqueue(
176
177
  executable: str,
177
178
  partition_wait_time: int,
178
179
  sleep_time: int,
179
- activities: Optional[Sequence[str]] = None,
180
- ) -> Callable[
181
- [
182
- Callable[
183
- ...,
184
- Union[bool, tuple[bool, T], None]
185
- ]
186
- ],
187
- Callable[
188
- [],
189
- Iterator[Union[T, None]]
190
- ]
191
- ]:
180
+ activities: Optional['Sequence[str]'] = None,
181
+ ) -> 'Callable[[Callable[..., Union[bool, tuple[bool, T], None]]], Callable[[], Iterator[Union[T, None]]]]':
192
182
  """
193
183
  Used to wrap a function for interacting with the database as a work queue: i.e. to select
194
184
  a set of rows and perform some work on those rows while ensuring that two instances running in parallel don't
@@ -203,10 +193,10 @@ def db_workqueue(
203
193
  :param activities: optional list of activities on which to work. The run_once_fnc will be called on activities one by one.
204
194
  """
205
195
 
206
- def _decorate(run_once_fnc: Callable[..., Optional[Union[bool, tuple[bool, T]]]]) -> Callable[[], Iterator[Optional[T]]]:
196
+ def _decorate(run_once_fnc: 'Callable[..., Optional[Union[bool, tuple[bool, T]]]]') -> 'Callable[[], Iterator[Optional[T]]]':
207
197
 
208
198
  @functools.wraps(run_once_fnc)
209
- def _generator() -> Iterator[T]:
199
+ def _generator() -> 'Iterator[T]':
210
200
 
211
201
  with HeartbeatHandler(executable=executable, renewal_interval=sleep_time - 1) as heartbeat_handler:
212
202
  logger = heartbeat_handler.logger
@@ -270,7 +260,7 @@ def run_daemon(
270
260
  executable: str,
271
261
  partition_wait_time: int,
272
262
  sleep_time: int,
273
- run_once_fnc: Callable[..., Optional[Union[bool, tuple[bool, Any]]]],
263
+ run_once_fnc: 'Callable[..., Optional[Union[bool, tuple[bool, Any]]]]',
274
264
  activities: Optional[list[str]] = None
275
265
  ) -> None:
276
266
  """
@@ -297,8 +287,8 @@ class ProducerConsumerDaemon(Generic[T]):
297
287
 
298
288
  def __init__(
299
289
  self,
300
- producers: Sequence[Callable[[], Iterator[T]]],
301
- consumers: Sequence[Callable[..., None]],
290
+ producers: 'Sequence[Callable[[], Iterator[T]]]',
291
+ consumers: 'Sequence[Callable[..., None]]',
302
292
  graceful_stop: threading.Event,
303
293
  logger: "LoggerFunction" = logging.log
304
294
  ):
@@ -314,7 +304,7 @@ class ProducerConsumerDaemon(Generic[T]):
314
304
 
315
305
  def _produce(
316
306
  self,
317
- it: Callable[[], Iterator[T]],
307
+ it: 'Callable[[], Iterator[T]]',
318
308
  wait_for_consumers: bool = False
319
309
  ) -> None:
320
310
  """
@@ -351,7 +341,7 @@ class ProducerConsumerDaemon(Generic[T]):
351
341
 
352
342
  def _consume(
353
343
  self,
354
- fnc: Callable[[T], Any]
344
+ fnc: 'Callable[[T], Any]'
355
345
  ) -> None:
356
346
  """
357
347
  Wait for elements to arrive via the queue and call the given function on each element.
@@ -29,7 +29,7 @@ from dogpile.cache.api import NoValue
29
29
  from sqlalchemy.exc import DatabaseError
30
30
 
31
31
  import rucio.db.sqla.util
32
- from rucio.common.cache import make_region_memcached
32
+ from rucio.common.cache import MemcacheRegion
33
33
  from rucio.common.config import config_get_bool, config_get_list
34
34
  from rucio.common.exception import DatabaseException, ReplicaNotFound, RequestNotFound, RSEProtocolNotSupported, UnsupportedOperation
35
35
  from rucio.common.logging import setup_logging
@@ -55,7 +55,7 @@ if TYPE_CHECKING:
55
55
 
56
56
  GRACEFUL_STOP = threading.Event()
57
57
 
58
- REGION = make_region_memcached(expiration_time=900)
58
+ REGION = MemcacheRegion(expiration_time=900)
59
59
  METRICS = MetricManager(module=__name__)
60
60
  DAEMON_NAME = 'conveyor-finisher'
61
61
  FAILED_DURING_SUBMISSION_DELAY = datetime.timedelta(minutes=120)
@@ -23,7 +23,6 @@ import logging
23
23
  import re
24
24
  import threading
25
25
  import time
26
- from collections.abc import Mapping, Sequence
27
26
  from itertools import groupby
28
27
  from typing import TYPE_CHECKING, Any, Optional
29
28
 
@@ -31,11 +30,10 @@ from requests.exceptions import RequestException
31
30
  from sqlalchemy.exc import DatabaseError
32
31
 
33
32
  import rucio.db.sqla.util
34
- from rucio.common.config import config_get, config_get_bool
33
+ from rucio.common.config import config_get, config_get_bool, config_get_float
35
34
  from rucio.common.exception import DatabaseException, TransferToolTimeout, TransferToolWrongAnswer
36
35
  from rucio.common.logging import setup_logging
37
36
  from rucio.common.stopwatch import Stopwatch
38
- from rucio.common.types import InternalAccount, LoggerFunction
39
37
  from rucio.common.utils import dict_chunks
40
38
  from rucio.core import request as request_core
41
39
  from rucio.core import transfer as transfer_core
@@ -44,12 +42,14 @@ from rucio.core.topology import ExpiringObjectCache, Topology
44
42
  from rucio.daemons.common import ProducerConsumerDaemon, db_workqueue
45
43
  from rucio.db.sqla.constants import MYSQL_LOCK_WAIT_TIMEOUT_EXCEEDED, ORACLE_DEADLOCK_DETECTED_REGEX, ORACLE_RESOURCE_BUSY_REGEX, RequestState, RequestType
46
44
  from rucio.transfertool.fts3 import FTS3Transfertool
47
- from rucio.transfertool.transfertool import Transfertool
48
45
 
49
46
  if TYPE_CHECKING:
47
+ from collections.abc import Mapping, Sequence
50
48
  from types import FrameType
51
49
 
50
+ from rucio.common.types import LoggerFunction
52
51
  from rucio.daemons.common import HeartbeatHandler
52
+ from rucio.transfertool.transfertool import Transfertool
53
53
 
54
54
  GRACEFUL_STOP = threading.Event()
55
55
  METRICS = MetricManager(module=__name__)
@@ -62,7 +62,7 @@ FILTER_TRANSFERTOOL = config_get('conveyor', 'filter_transfertool', False, None)
62
62
  def _fetch_requests(
63
63
  db_bulk: int,
64
64
  older_than: int,
65
- activity_shares: Optional[Mapping[str, float]],
65
+ activity_shares: Optional['Mapping[str, float]'],
66
66
  transfertool: Optional[str],
67
67
  filter_transfertool: Optional[str],
68
68
  cached_topology: Optional[ExpiringObjectCache],
@@ -116,9 +116,9 @@ def _handle_requests(
116
116
  timeout: Optional[int],
117
117
  transfertool: str,
118
118
  transfer_stats_manager: request_core.TransferStatsManager,
119
- oidc_account: Optional[str],
119
+ oidc_support: bool,
120
120
  *,
121
- logger: LoggerFunction = logging.log,
121
+ logger: "LoggerFunction" = logging.log,
122
122
  ) -> None:
123
123
  transfs.sort(key=lambda t: (t['external_host'] or '',
124
124
  t['scope'].vo if multi_vo else '',
@@ -136,15 +136,9 @@ def _handle_requests(
136
136
 
137
137
  transfertool_kwargs = {}
138
138
  if transfertool_cls.external_name == FTS3Transfertool.external_name:
139
- account = None
140
- if oidc_account:
141
- if vo:
142
- account = InternalAccount(oidc_account, vo=vo)
143
- else:
144
- account = InternalAccount(oidc_account)
145
139
  transfertool_kwargs.update({
146
140
  'vo': vo,
147
- 'oidc_account': account,
141
+ 'oidc_support': oidc_support,
148
142
  })
149
143
 
150
144
  transfertool_obj = transfertool_cls(external_host=external_host, **transfertool_kwargs)
@@ -161,12 +155,12 @@ def _handle_requests(
161
155
 
162
156
  def poller(
163
157
  once: bool = False,
164
- activities: Optional[Sequence[str]] = None,
158
+ activities: Optional['Sequence[str]'] = None,
165
159
  sleep_time: int = 60,
166
160
  fts_bulk: int = 100,
167
161
  db_bulk: int = 1000,
168
162
  older_than: int = 60,
169
- activity_shares: Optional[Mapping[str, float]] = None,
163
+ activity_shares: Optional['Mapping[str, float]'] = None,
170
164
  partition_wait_time: int = 10,
171
165
  transfertool: Optional[str] = TRANSFER_TOOL,
172
166
  filter_transfertool: Optional[str] = FILTER_TRANSFERTOOL,
@@ -176,13 +170,9 @@ def poller(
176
170
  """
177
171
  Main loop to check the status of a transfer primitive with a transfertool.
178
172
  """
179
-
180
- timeout = config_get('conveyor', 'poll_timeout', default=None, raise_exception=False)
181
- if timeout:
182
- timeout = float(timeout)
183
-
173
+ timeout = config_get_float('conveyor', 'poll_timeout', default=None, raise_exception=False)
184
174
  multi_vo = config_get_bool('common', 'multi_vo', False, None)
185
- oidc_account = config_get('conveyor', 'poller_oidc_account', False, None)
175
+ oidc_support = config_get_bool('conveyor', 'poller_oidc_support', default=False, raise_exception=False)
186
176
 
187
177
  executable = DAEMON_NAME
188
178
 
@@ -227,7 +217,7 @@ def poller(
227
217
  fts_bulk=fts_bulk,
228
218
  multi_vo=multi_vo,
229
219
  timeout=timeout, # type: ignore (unclear if timeout is meant to be int or float)
230
- oidc_account=oidc_account,
220
+ oidc_support=oidc_support,
231
221
  transfertool=transfertool, # type: ignore (transfertool is not None)
232
222
  transfer_stats_manager=transfer_stats_manager,
233
223
  )
@@ -251,7 +241,7 @@ def stop(signum: Optional[int] = None, frame: Optional["FrameType"] = None) -> N
251
241
  def run(
252
242
  once: bool = False,
253
243
  sleep_time: int = 60,
254
- activities: Optional[Sequence[str]] = None,
244
+ activities: Optional['Sequence[str]'] = None,
255
245
  fts_bulk: int = 100,
256
246
  db_bulk: int = 1000,
257
247
  older_than: int = 60,
@@ -301,8 +291,8 @@ def run(
301
291
 
302
292
 
303
293
  def poll_transfers(
304
- transfertool_obj: Transfertool,
305
- transfers_by_eid: Mapping[str, Mapping[str, Any]],
294
+ transfertool_obj: 'Transfertool',
295
+ transfers_by_eid: 'Mapping[str, Mapping[str, Any]]',
306
296
  transfer_stats_manager: request_core.TransferStatsManager,
307
297
  timeout: "Optional[int]" = None,
308
298
  logger: "LoggerFunction" = logging.log
@@ -328,8 +318,8 @@ def poll_transfers(
328
318
 
329
319
 
330
320
  def _poll_transfers(
331
- transfertool_obj: Transfertool,
332
- transfers_by_eid: Mapping[str, Mapping[str, Any]],
321
+ transfertool_obj: 'Transfertool',
322
+ transfers_by_eid: 'Mapping[str, Mapping[str, Any]]',
333
323
  transfer_stats_manager: request_core.TransferStatsManager,
334
324
  timeout: "Optional[int]" = None,
335
325
  logger: "LoggerFunction" = logging.log