Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Side by Side Diff: scripts/master/master_utils.py

Issue 2427413005: Improve slave-preference function (Closed)
Patch Set: Improve slave preference function Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import os 5 import os
6 import random 6 import random
7 import re 7 import re
8 import sys 8 import sys
9 9
10 import buildbot 10 import buildbot
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 648
649 # Choose our inner IRenderer and render it 649 # Choose our inner IRenderer and render it
650 renderer = (self.present) if is_present else (self.absent) 650 renderer = (self.present) if is_present else (self.absent)
651 # Disable 'too many positional arguments' error | pylint: disable=E1121 651 # Disable 'too many positional arguments' error | pylint: disable=E1121
652 return IRenderable(renderer).getRenderingFor(build) 652 return IRenderable(renderer).getRenderingFor(build)
653 653
654 654
655 class PreferredBuilderNextSlaveFunc(object): 655 class PreferredBuilderNextSlaveFunc(object):
656 """ 656 """
657 This object, when used as a Builder's 'nextSlave' function, will choose 657 This object, when used as a Builder's 'nextSlave' function, will choose
658 a slave builder whose 'preferred_builder' value is the same as the builder 658 a slave whose 'preferred_builder' value is the same as the builder
659 name. If there is no such a builder, a builder is randomly chosen. 659 name. If there is no such slave, a slave is randomly chosen that doesn't
660 prefer any builder if such a slave is available. If not, a slave is randomly
661 chosen with preference on slaves with higher capacity.
660 """ 662 """
661 663
664 def __init__(self, choice=random.choice):
665 # Allow overriding the choice function for testability.
666 self.choice = choice
667
662 def __call__(self, builder, slave_builders): 668 def __call__(self, builder, slave_builders):
663 if not slave_builders: 669 if not slave_builders:
664 return None 670 return None
665 671
tandrii(chromium) 2016/10/21 10:39:16 first, consider adding new functionality behind a
Michael Achenbach 2016/10/21 13:17:43 Used the first simple method with minor modificati
672 # First choice: Slaves that prefer this builder.
666 preferred_slaves = [ 673 preferred_slaves = [
667 s for s in slave_builders 674 s for s in slave_builders
668 if s.slave.properties.getProperty('preferred_builder') == builder.name] 675 if s.slave.properties.getProperty('preferred_builder') == builder.name]
669 return random.choice(preferred_slaves or slave_builders) 676 if preferred_slaves:
677 return self.choice(preferred_slaves)
678
679 # Second choice: Slaves that don't prefer any builders.
680 preferred_slaves = [
681 s for s in slave_builders
682 if not s.slave.properties.getProperty('preferred_builder')]
683 if preferred_slaves:
684 return self.choice(preferred_slaves)
685
686 # Third choice: Slaves that prefer other builders but have largest
687 # capacity left.
688 preference_to_slaves = {}
689 largest_capacity = 0
690 for s in slave_builders:
691 # There should only be slaves with preference left, but lets be
692 # defensive.
693 preference = s.slave.properties.getProperty('preferred_builder')
694 if preference:
695 slaves = preference_to_slaves.setdefault(preference, [])
696 slaves.append(s)
697 largest_capacity = max(largest_capacity, len(slaves))
698 # Prefer list over set as each slave has only one preferred builder.
699 preferred_slaves = []
700 for preference, slaves in preference_to_slaves.iteritems():
701 if len(slaves) == largest_capacity:
702 preferred_slaves.extend(slaves)
703 if preferred_slaves:
704 return self.choice(preferred_slaves)
705
706 # Last choice: Choose from all slaves. We should never reach here as all
707 # slaves should have been considered above.
708 log.err('Didn\'t get preferred slave for %s' % builder.name)
709 return self.choice(slave_builders)
670 710
671 711
672 def SetMasterProcessName(): 712 def SetMasterProcessName():
673 """Sets the name of this process to the name of the master. Linux only.""" 713 """Sets the name of this process to the name of the master. Linux only."""
674 714
675 if sys.platform != 'linux2': 715 if sys.platform != 'linux2':
676 return 716 return
677 717
678 command_line.set_command_line("master: %s" % GetMastername()) 718 command_line.set_command_line("master: %s" % GetMastername())
OLDNEW
« no previous file with comments | « no previous file | scripts/master/unittests/master_utils_test.py » ('j') | scripts/master/unittests/master_utils_test.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698