Repository: rucio/rucio

Issue:
Partitioning algorithm wrong for thread_id=0
Motivation
----------
The partitioning algorithm is not working correctly for `thread_id=0`. It then wrongly goes to a mode assuming there are no partitions.

Modify RSEs regex for Belleii schema
Motivation
----------
The current regex doesn't fit to Belle2 convention




Discussion:

+ New naming convention

Resolving patch:
diff --git a/lib/rucio/common/schema/belleii.py b/lib/rucio/common/schema/belleii.py
--- a/lib/rucio/common/schema/belleii.py
+++ b/lib/rucio/common/schema/belleii.py
@@ -15,6 +15,7 @@
 # Authors:
 # - Martin Barisits <martin.barisits@cern.ch>, 2019
 # - Mario Lassnig <mario.lassnig@cern.ch>, 2019
+# - Cedric Serfon <cedric.serfon@cern.ch>, 2020
 #
 # PY3K COMPATIBLE
 
@@ -84,7 +85,7 @@
 
 RSE = {"description": "RSE name",
        "type": "string",
-       "pattern": "^([A-Z0-9]+([_-][A-Z0-9]+)*)$"}
+       "pattern": "^([A-Z])+((([A-Za-z0-9]+))*(-)?)*$"}
 
 RSE_ATTRIBUTE = {"description": "RSE attribute",
                  "type": "string",
diff --git a/lib/rucio/db/sqla/__init__.py b/lib/rucio/db/sqla/__init__.py
--- a/lib/rucio/db/sqla/__init__.py
+++ b/lib/rucio/db/sqla/__init__.py
@@ -9,7 +9,7 @@
 
 def filter_thread_work(session, query, total_threads, thread_id, hash_variable=None):
     """ Filters a query to partition thread workloads based on the thread id and total number of threads """
-    if thread_id and total_threads and (total_threads - 1) > 0:
+    if thread_id is not None and total_threads is not None and (total_threads - 1) > 0:
         if session.bind.dialect.name == 'oracle':
             bindparams = [bindparam('thread_id', thread_id), bindparam('total_threads', total_threads - 1)]
             if not hash_variable:
diff --git a/lib/rucio/rse/protocols/protocol.py b/lib/rucio/rse/protocols/protocol.py
--- a/lib/rucio/rse/protocols/protocol.py
+++ b/lib/rucio/rse/protocols/protocol.py
@@ -16,7 +16,7 @@
 # - Ralph Vigne <ralph.vigne@cern.ch>, 2012-2014
 # - Vincent Garonne <vgaronne@gmail.com>, 2012-2016
 # - Mario Lassnig <mario.lassnig@cern.ch>, 2013-2019
-# - Cedric Serfon <cedric.serfon@cern.ch>, 2013-2016
+# - Cedric Serfon <cedric.serfon@cern.ch>, 2013-2020
 # - Wen Guan <wguan.icedew@gmail.com>, 2014-2017
 # - Cheng-Hsi Chao <cheng-hsi.chao@cern.ch>, 2014
 # - Tobias Wegner <twegner@cern.ch>, 2017
@@ -153,6 +153,28 @@ def __identity(scope, name, rse, rse_attrs, protocol_attrs):
             scope = scope.replace('.', '/')
         return '%s/%s' % (scope, name)
 
+    @staticmethod
+    def __belleii(scope, name, rse, rse_attrs, protocol_attrs):
+        """
+        Given a LFN, convert it directly to a path using the mapping:
+
+            path -> path
+        This is valid only for the belleii convention where the scope can be determined
+        from the LFN using a determinitic function.
+
+        :param scope: Scope of the LFN.
+        :param name: File name of the LFN.
+        :param rse: RSE for PFN (ignored)
+        :param rse_attrs: RSE attributes for PFN (ignored)
+        :param protocol_attrs: RSE protocol attributes for PFN (ignored)
+        :returns: Path for use in the PFN generation.
+        """
+        del scope
+        del rse
+        del rse_attrs
+        del protocol_attrs
+        return name
+
     @staticmethod
     def __ligo(scope, name, rse, rse_attrs, protocol_attrs):
         """
@@ -182,6 +204,7 @@ def _module_init_(cls):
         cls.register(cls.__hash, "hash")
         cls.register(cls.__identity, "identity")
         cls.register(cls.__ligo, "ligo")
+        cls.register(cls.__belleii, "belleii")
         policy_module = None
         try:
             policy_module = config.config_get('policy', 'lfn2pfn_module')


Test patch: