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.
- rucio/alembicrevision.py +1 -1
- rucio/{daemons/c3po/collectors → cli}/__init__.py +1 -0
- rucio/cli/account.py +216 -0
- rucio-35.7.0.data/scripts/rucio → rucio/cli/bin_legacy/rucio.py +769 -486
- rucio-35.7.0.data/scripts/rucio-admin → rucio/cli/bin_legacy/rucio_admin.py +476 -423
- rucio/cli/command.py +272 -0
- rucio/cli/config.py +72 -0
- rucio/cli/did.py +191 -0
- rucio/cli/download.py +128 -0
- rucio/cli/lifetime_exception.py +33 -0
- rucio/cli/replica.py +162 -0
- rucio/cli/rse.py +293 -0
- rucio/cli/rule.py +158 -0
- rucio/cli/scope.py +40 -0
- rucio/cli/subscription.py +73 -0
- rucio/cli/upload.py +60 -0
- rucio/cli/utils.py +226 -0
- rucio/client/accountclient.py +0 -1
- rucio/client/baseclient.py +33 -24
- rucio/client/client.py +45 -1
- rucio/client/didclient.py +5 -3
- rucio/client/downloadclient.py +6 -8
- rucio/client/replicaclient.py +0 -2
- rucio/client/richclient.py +317 -0
- rucio/client/rseclient.py +4 -4
- rucio/client/uploadclient.py +26 -12
- rucio/common/bittorrent.py +234 -0
- rucio/common/cache.py +66 -29
- rucio/common/checksum.py +168 -0
- rucio/common/client.py +122 -0
- rucio/common/config.py +22 -35
- rucio/common/constants.py +61 -3
- rucio/common/didtype.py +72 -24
- rucio/common/dumper/__init__.py +45 -38
- rucio/common/dumper/consistency.py +75 -30
- rucio/common/dumper/data_models.py +63 -19
- rucio/common/dumper/path_parsing.py +19 -8
- rucio/common/exception.py +65 -8
- rucio/common/extra.py +5 -10
- rucio/common/logging.py +13 -13
- rucio/common/pcache.py +8 -7
- rucio/common/plugins.py +59 -27
- rucio/common/policy.py +12 -3
- rucio/common/schema/__init__.py +84 -34
- rucio/common/schema/generic.py +0 -17
- rucio/common/schema/generic_multi_vo.py +0 -17
- rucio/common/stomp_utils.py +383 -119
- rucio/common/test_rucio_server.py +12 -6
- rucio/common/types.py +132 -52
- rucio/common/utils.py +93 -643
- rucio/core/account_limit.py +14 -12
- rucio/core/authentication.py +2 -2
- rucio/core/config.py +23 -42
- rucio/core/credential.py +14 -15
- rucio/core/did.py +5 -1
- rucio/core/did_meta_plugins/elasticsearch_meta.py +407 -0
- rucio/core/did_meta_plugins/filter_engine.py +62 -3
- rucio/core/did_meta_plugins/json_meta.py +2 -2
- rucio/core/did_meta_plugins/mongo_meta.py +43 -30
- rucio/core/did_meta_plugins/postgres_meta.py +75 -39
- rucio/core/identity.py +6 -5
- rucio/core/importer.py +4 -3
- rucio/core/lifetime_exception.py +2 -2
- rucio/core/lock.py +8 -7
- rucio/core/message.py +6 -0
- rucio/core/monitor.py +30 -29
- rucio/core/naming_convention.py +2 -2
- rucio/core/nongrid_trace.py +2 -2
- rucio/core/oidc.py +11 -9
- rucio/core/permission/__init__.py +79 -37
- rucio/core/permission/generic.py +1 -7
- rucio/core/permission/generic_multi_vo.py +1 -7
- rucio/core/quarantined_replica.py +4 -3
- rucio/core/replica.py +464 -139
- rucio/core/replica_sorter.py +55 -59
- rucio/core/request.py +34 -32
- rucio/core/rse.py +301 -97
- rucio/core/rse_counter.py +1 -2
- rucio/core/rse_expression_parser.py +7 -7
- rucio/core/rse_selector.py +9 -7
- rucio/core/rule.py +41 -40
- rucio/core/rule_grouping.py +42 -40
- rucio/core/scope.py +5 -4
- rucio/core/subscription.py +26 -28
- rucio/core/topology.py +11 -11
- rucio/core/trace.py +2 -2
- rucio/core/transfer.py +29 -15
- rucio/core/volatile_replica.py +4 -3
- rucio/daemons/atropos/atropos.py +1 -1
- rucio/daemons/auditor/__init__.py +2 -2
- rucio/daemons/auditor/srmdumps.py +6 -6
- rucio/daemons/automatix/automatix.py +32 -21
- rucio/daemons/badreplicas/necromancer.py +2 -2
- rucio/daemons/bb8/nuclei_background_rebalance.py +1 -1
- rucio/daemons/bb8/t2_background_rebalance.py +1 -1
- rucio/daemons/cache/consumer.py +26 -90
- rucio/daemons/common.py +15 -25
- rucio/daemons/conveyor/finisher.py +2 -2
- rucio/daemons/conveyor/poller.py +18 -28
- rucio/daemons/conveyor/receiver.py +53 -123
- rucio/daemons/conveyor/stager.py +1 -0
- rucio/daemons/conveyor/submitter.py +3 -3
- rucio/daemons/hermes/hermes.py +129 -369
- rucio/daemons/judge/evaluator.py +2 -2
- rucio/daemons/oauthmanager/oauthmanager.py +3 -3
- rucio/daemons/reaper/dark_reaper.py +7 -3
- rucio/daemons/reaper/reaper.py +12 -16
- rucio/daemons/rsedecommissioner/config.py +1 -1
- rucio/daemons/rsedecommissioner/profiles/generic.py +5 -4
- rucio/daemons/rsedecommissioner/profiles/types.py +7 -6
- rucio/daemons/rsedecommissioner/rse_decommissioner.py +1 -1
- rucio/daemons/storage/consistency/actions.py +8 -6
- rucio/daemons/tracer/kronos.py +117 -142
- rucio/db/sqla/constants.py +5 -0
- rucio/db/sqla/migrate_repo/versions/1677d4d803c8_split_rse_availability_into_multiple.py +4 -4
- rucio/db/sqla/migrate_repo/versions/30d5206e9cad_increase_oauthrequest_redirect_msg_.py +37 -0
- rucio/db/sqla/models.py +157 -154
- rucio/db/sqla/session.py +58 -27
- rucio/db/sqla/types.py +2 -2
- rucio/db/sqla/util.py +2 -2
- rucio/gateway/account.py +18 -12
- rucio/gateway/account_limit.py +137 -60
- rucio/gateway/authentication.py +18 -12
- rucio/gateway/config.py +30 -20
- rucio/gateway/credential.py +9 -10
- rucio/gateway/did.py +70 -53
- rucio/gateway/dirac.py +6 -4
- rucio/gateway/exporter.py +3 -2
- rucio/gateway/heartbeat.py +6 -4
- rucio/gateway/identity.py +36 -51
- rucio/gateway/importer.py +3 -2
- rucio/gateway/lifetime_exception.py +3 -2
- rucio/gateway/meta_conventions.py +17 -6
- rucio/gateway/permission.py +4 -1
- rucio/gateway/quarantined_replica.py +3 -2
- rucio/gateway/replica.py +31 -22
- rucio/gateway/request.py +27 -18
- rucio/gateway/rse.py +69 -37
- rucio/gateway/rule.py +46 -26
- rucio/gateway/scope.py +3 -2
- rucio/gateway/subscription.py +14 -11
- rucio/gateway/vo.py +12 -8
- rucio/rse/__init__.py +3 -3
- rucio/rse/protocols/bittorrent.py +11 -1
- rucio/rse/protocols/cache.py +0 -11
- rucio/rse/protocols/dummy.py +0 -11
- rucio/rse/protocols/gfal.py +14 -9
- rucio/rse/protocols/globus.py +1 -1
- rucio/rse/protocols/http_cache.py +1 -1
- rucio/rse/protocols/posix.py +2 -2
- rucio/rse/protocols/protocol.py +84 -317
- rucio/rse/protocols/rclone.py +2 -1
- rucio/rse/protocols/rfio.py +10 -1
- rucio/rse/protocols/ssh.py +2 -1
- rucio/rse/protocols/storm.py +2 -13
- rucio/rse/protocols/webdav.py +74 -30
- rucio/rse/protocols/xrootd.py +2 -1
- rucio/rse/rsemanager.py +170 -53
- rucio/rse/translation.py +260 -0
- rucio/tests/common.py +23 -13
- rucio/tests/common_server.py +26 -9
- rucio/transfertool/bittorrent.py +15 -14
- rucio/transfertool/bittorrent_driver.py +5 -7
- rucio/transfertool/bittorrent_driver_qbittorrent.py +9 -8
- rucio/transfertool/fts3.py +20 -16
- rucio/transfertool/mock.py +2 -3
- rucio/vcsversion.py +4 -4
- rucio/version.py +7 -0
- rucio/web/rest/flaskapi/v1/accounts.py +17 -3
- rucio/web/rest/flaskapi/v1/auth.py +5 -5
- rucio/web/rest/flaskapi/v1/credentials.py +3 -2
- rucio/web/rest/flaskapi/v1/dids.py +21 -15
- rucio/web/rest/flaskapi/v1/identities.py +33 -9
- rucio/web/rest/flaskapi/v1/redirect.py +5 -4
- rucio/web/rest/flaskapi/v1/replicas.py +12 -8
- rucio/web/rest/flaskapi/v1/rses.py +15 -4
- rucio/web/rest/flaskapi/v1/traces.py +56 -19
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/alembic.ini.template +1 -1
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/alembic_offline.ini.template +1 -1
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/rucio.cfg.atlas.client.template +3 -2
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/rucio.cfg.template +3 -19
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/rucio_multi_vo.cfg.template +1 -18
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/requirements.server.txt +97 -68
- rucio-37.0.0rc2.data/scripts/rucio +133 -0
- rucio-37.0.0rc2.data/scripts/rucio-admin +97 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-atropos +2 -2
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-auditor +2 -1
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-automatix +2 -2
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-cache-client +17 -10
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-receiver +1 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-kronos +1 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-minos +2 -2
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-minos-temporary-expiration +2 -2
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-necromancer +2 -2
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-reaper +6 -6
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-transmogrifier +2 -2
- rucio-37.0.0rc2.dist-info/METADATA +92 -0
- {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/RECORD +239 -245
- {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/licenses/AUTHORS.rst +3 -0
- rucio/common/schema/atlas.py +0 -413
- rucio/common/schema/belleii.py +0 -408
- rucio/common/schema/domatpc.py +0 -401
- rucio/common/schema/escape.py +0 -426
- rucio/common/schema/icecube.py +0 -406
- rucio/core/permission/atlas.py +0 -1348
- rucio/core/permission/belleii.py +0 -1077
- rucio/core/permission/escape.py +0 -1078
- rucio/daemons/c3po/algorithms/__init__.py +0 -13
- rucio/daemons/c3po/algorithms/simple.py +0 -134
- rucio/daemons/c3po/algorithms/t2_free_space.py +0 -128
- rucio/daemons/c3po/algorithms/t2_free_space_only_pop.py +0 -130
- rucio/daemons/c3po/algorithms/t2_free_space_only_pop_with_network.py +0 -294
- rucio/daemons/c3po/c3po.py +0 -371
- rucio/daemons/c3po/collectors/agis.py +0 -108
- rucio/daemons/c3po/collectors/free_space.py +0 -81
- rucio/daemons/c3po/collectors/jedi_did.py +0 -57
- rucio/daemons/c3po/collectors/mock_did.py +0 -51
- rucio/daemons/c3po/collectors/network_metrics.py +0 -71
- rucio/daemons/c3po/collectors/workload.py +0 -112
- rucio/daemons/c3po/utils/__init__.py +0 -13
- rucio/daemons/c3po/utils/dataset_cache.py +0 -50
- rucio/daemons/c3po/utils/expiring_dataset_cache.py +0 -56
- rucio/daemons/c3po/utils/expiring_list.py +0 -62
- rucio/daemons/c3po/utils/popularity.py +0 -85
- rucio/daemons/c3po/utils/timeseries.py +0 -89
- rucio/rse/protocols/gsiftp.py +0 -92
- rucio-35.7.0.data/scripts/rucio-c3po +0 -85
- rucio-35.7.0.dist-info/METADATA +0 -72
- /rucio/{daemons/c3po → cli/bin_legacy}/__init__.py +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/globus-config.yml.template +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/ldap.cfg.template +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_approval_request.tmpl +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_approved_admin.tmpl +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_approved_user.tmpl +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_denied_admin.tmpl +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_denied_user.tmpl +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/mail_templates/rule_ok_notification.tmpl +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/etc/rse-accounts.cfg.template +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/tools/bootstrap.py +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/tools/merge_rucio_configs.py +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/data/rucio/tools/reset_database.py +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-abacus-account +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-abacus-collection-replica +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-abacus-rse +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-bb8 +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-cache-consumer +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-finisher +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-poller +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-preparer +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-stager +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-submitter +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-conveyor-throttler +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-dark-reaper +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-dumper +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-follower +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-hermes +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-judge-cleaner +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-judge-evaluator +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-judge-injector +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-judge-repairer +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-oauth-manager +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-replica-recoverer +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-rse-decommissioner +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-storage-consistency-actions +0 -0
- {rucio-35.7.0.data → rucio-37.0.0rc2.data}/scripts/rucio-undertaker +0 -0
- {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/WHEEL +0 -0
- {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/licenses/LICENSE +0 -0
- {rucio-35.7.0.dist-info → rucio-37.0.0rc2.dist-info}/top_level.txt +0 -0
rucio/daemons/cache/consumer.py
CHANGED
|
@@ -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
|
|
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.
|
|
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 =
|
|
70
|
+
rse_vo_str = f"{rse_vo_str} on {msg['vo']}"
|
|
97
71
|
if msg['operation'] == 'add_replicas':
|
|
98
|
-
self.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
101
|
+
conn_mgr.disconnect()
|
|
167
102
|
logger(logging.INFO, 'graceful stop done')
|
|
168
103
|
|
|
169
104
|
|
|
170
|
-
def stop(signum:
|
|
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.
|
|
188
|
-
threads = [
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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.
|
|
130
|
+
logger(logging.INFO, 'waiting for interrupts')
|
|
194
131
|
|
|
195
|
-
|
|
196
|
-
|
|
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
|
|
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 =
|
|
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)
|
rucio/daemons/conveyor/poller.py
CHANGED
|
@@ -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
|
-
|
|
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
|
-
'
|
|
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
|
-
|
|
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
|
-
|
|
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
|