summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-03-20 22:47:14 +0000
committerGerrit Code Review <review@openstack.org>2018-03-20 22:47:14 +0000
commit7bacb38c76afecf6108e1162611f5afc14faba67 (patch)
tree6d682992fa14446108f7550aebfb7735fc7b5acb
parent0b649d538749c9e80d2a7cf3efea06d0b198e4d6 (diff)
parent9f4910f6b938aa1679571d4787bbdcfa5b5f3a19 (diff)
downloadswift-7bacb38c76afecf6108e1162611f5afc14faba67.tar.gz
Merge "Add round_robin_iter function to common/utils"
-rw-r--r--swift/common/db_replicator.py12
-rw-r--r--swift/common/utils.py14
-rw-r--r--test/unit/common/test_utils.py13
3 files changed, 32 insertions, 7 deletions
diff --git a/swift/common/db_replicator.py b/swift/common/db_replicator.py
index cd93e8b4e..3b456cd8b 100644
--- a/swift/common/db_replicator.py
+++ b/swift/common/db_replicator.py
@@ -33,7 +33,7 @@ from swift.common.direct_client import quote
from swift.common.utils import get_logger, whataremyips, storage_directory, \
renamer, mkdirs, lock_parent_directory, config_true_value, \
unlink_older_than, dump_recon_cache, rsync_module_interpolation, \
- json, Timestamp, parse_overrides
+ json, Timestamp, parse_overrides, round_robin_iter
from swift.common import ring
from swift.common.ring.utils import is_local_device
from swift.common.http import HTTP_NOT_FOUND, HTTP_INSUFFICIENT_STORAGE
@@ -127,12 +127,10 @@ def roundrobin_datadirs(datadirs):
its = [walk_datadir(datadir, node_id, filt)
for datadir, node_id, filt in datadirs]
- while its:
- for it in its:
- try:
- yield next(it)
- except StopIteration:
- its.remove(it)
+
+ rr_its = round_robin_iter(its)
+ for datadir in rr_its:
+ yield datadir
class ReplConnection(BufferedHTTPConnection):
diff --git a/swift/common/utils.py b/swift/common/utils.py
index 2e46282cb..2e15594b1 100644
--- a/swift/common/utils.py
+++ b/swift/common/utils.py
@@ -4642,3 +4642,17 @@ class PipeMutex(object):
class ThreadSafeSysLogHandler(SysLogHandler):
def createLock(self):
self.lock = PipeMutex()
+
+
+def round_robin_iter(its):
+ """
+ Takes a list of iterators, yield an element from each in a round-robin
+ fashion until all of them are exhausted.
+ :param its: list of iterators
+ """
+ while its:
+ for it in its:
+ try:
+ yield next(it)
+ except StopIteration:
+ its.remove(it)
diff --git a/test/unit/common/test_utils.py b/test/unit/common/test_utils.py
index 23babd13c..893bb18ba 100644
--- a/test/unit/common/test_utils.py
+++ b/test/unit/common/test_utils.py
@@ -4027,6 +4027,19 @@ cluster_dfw1 = http://dfw1.host/v1/
self.assertEqual(utils.replace_partition_in_path(old, 10), old)
self.assertEqual(utils.replace_partition_in_path(new, 11), new)
+ def test_round_robin_iter(self):
+ it1 = iter([1, 2, 3])
+ it2 = iter([4, 5])
+ it3 = iter([6, 7, 8, 9])
+ it4 = iter([])
+
+ rr_its = utils.round_robin_iter([it1, it2, it3, it4])
+ got = list(rr_its)
+
+ # Expect that items get fetched in a round-robin fashion from the
+ # iterators
+ self.assertListEqual([1, 4, 6, 2, 5, 7, 3, 8, 9], got)
+
class ResellerConfReader(unittest.TestCase):