* Use polling to wait for a remote build slot when using a build hook
(that is, call the build hook with a certain interval until it accepts the build). * build-remote.pl was totally broken: for all system types other than the local system type, it would send all builds to the *first* machine of the appropriate type.
This commit is contained in:
		
							parent
							
								
									47706e3924
								
							
						
					
					
						commit
						737423a89c
					
				
					 2 changed files with 3 additions and 36 deletions
				
			
		| 
						 | 
					@ -23,8 +23,7 @@ use English '-no_match_vars';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
my $loadIncreased = 0;
 | 
					my $loadIncreased = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
my ($amWilling, $localSystem, $neededSystem, $drvPath, $mustRun, $maxSilentTime) = @ARGV;
 | 
					my ($amWilling, $localSystem, $neededSystem, $drvPath, $maxSilentTime) = @ARGV;
 | 
				
			||||||
$mustRun = 0 unless defined $mustRun;
 | 
					 | 
				
			||||||
$maxSilentTime = 0 unless defined $maxSilentTime;
 | 
					$maxSilentTime = 0 unless defined $maxSilentTime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sub sendReply {
 | 
					sub sendReply {
 | 
				
			||||||
| 
						 | 
					@ -87,12 +86,10 @@ LOOP: foreach my $cur (@machines) {
 | 
				
			||||||
        # We have a machine of the right type.  Try to get a lock on
 | 
					        # We have a machine of the right type.  Try to get a lock on
 | 
				
			||||||
        # one of the machine's lock files.
 | 
					        # one of the machine's lock files.
 | 
				
			||||||
        my $slot = 0;
 | 
					        my $slot = 0;
 | 
				
			||||||
        while ($slot < $cur->{maxJobs} || ($mustRun && !$canBuildLocally)) {
 | 
					        while ($slot < $cur->{maxJobs}) {
 | 
				
			||||||
            my $slotLock = "$currentLoad/" . $cur->{systemType} . "-" . $cur->{hostName} . "-$slot";
 | 
					            my $slotLock = "$currentLoad/" . $cur->{systemType} . "-" . $cur->{hostName} . "-$slot";
 | 
				
			||||||
            open SLOTLOCK, ">>$slotLock" or die;
 | 
					            open SLOTLOCK, ">>$slotLock" or die;
 | 
				
			||||||
            if (flock(SLOTLOCK, LOCK_EX | LOCK_NB)) {
 | 
					            if (flock(SLOTLOCK, LOCK_EX | LOCK_NB)) {
 | 
				
			||||||
                print STDERR "warning: exceeding maximum load on " . $cur->{systemType} . "\n"
 | 
					 | 
				
			||||||
                    if $slot >= $cur->{maxJobs};
 | 
					 | 
				
			||||||
                $machine = $cur;
 | 
					                $machine = $cur;
 | 
				
			||||||
                last LOOP;
 | 
					                last LOOP;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,9 +52,6 @@ namespace nix {
 | 
				
			||||||
using std::map;
 | 
					using std::map;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* !!! TODO derivationFromPath shouldn't be used here */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static string pathNullDevice = "/dev/null";
 | 
					static string pathNullDevice = "/dev/null";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -229,9 +226,6 @@ public:
 | 
				
			||||||
    /* Can we start another child process? */
 | 
					    /* Can we start another child process? */
 | 
				
			||||||
    bool canBuildMore();
 | 
					    bool canBuildMore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Can we postpone a build right now? */
 | 
					 | 
				
			||||||
    bool canPostpone();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Registers a running child process.  `inBuildSlot' means that
 | 
					    /* Registers a running child process.  `inBuildSlot' means that
 | 
				
			||||||
       the process counts towards the jobs limit. */
 | 
					       the process counts towards the jobs limit. */
 | 
				
			||||||
    void childStarted(GoalPtr goal, pid_t pid,
 | 
					    void childStarted(GoalPtr goal, pid_t pid,
 | 
				
			||||||
| 
						 | 
					@ -247,10 +241,6 @@ public:
 | 
				
			||||||
       might be right away). */
 | 
					       might be right away). */
 | 
				
			||||||
    void waitForBuildSlot(GoalPtr goal);
 | 
					    void waitForBuildSlot(GoalPtr goal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Put `goal' to sleep until a child process terminates, i.e., a
 | 
					 | 
				
			||||||
       call is made to childTerminate(..., true).  */
 | 
					 | 
				
			||||||
    void waitForChildTermination(GoalPtr goal);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Wait for any goal to finish.  Pretty indiscriminate way to
 | 
					    /* Wait for any goal to finish.  Pretty indiscriminate way to
 | 
				
			||||||
       wait for some resource that some other goal is holding. */
 | 
					       wait for some resource that some other goal is holding. */
 | 
				
			||||||
    void waitForAnyGoal(GoalPtr goal);
 | 
					    void waitForAnyGoal(GoalPtr goal);
 | 
				
			||||||
| 
						 | 
					@ -1041,7 +1031,7 @@ void DerivationGoal::tryToBuild()
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        case rpPostpone:
 | 
					        case rpPostpone:
 | 
				
			||||||
            /* Not now; wait until at least one child finishes. */
 | 
					            /* Not now; wait until at least one child finishes. */
 | 
				
			||||||
            worker.waitForChildTermination(shared_from_this());
 | 
					            worker.waitForAWhile(shared_from_this());
 | 
				
			||||||
            outputLocks.unlock();
 | 
					            outputLocks.unlock();
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        case rpDecline:
 | 
					        case rpDecline:
 | 
				
			||||||
| 
						 | 
					@ -1246,7 +1236,6 @@ DerivationGoal::HookReply DerivationGoal::tryBuildHook()
 | 
				
			||||||
                thisSystem.c_str(),
 | 
					                thisSystem.c_str(),
 | 
				
			||||||
                drv.platform.c_str(),
 | 
					                drv.platform.c_str(),
 | 
				
			||||||
                drvPath.c_str(),
 | 
					                drvPath.c_str(),
 | 
				
			||||||
                (worker.canPostpone() ? (string) "0" : "1").c_str(),
 | 
					 | 
				
			||||||
                (format("%1%") % maxSilentTime).str().c_str(),
 | 
					                (format("%1%") % maxSilentTime).str().c_str(),
 | 
				
			||||||
                NULL);
 | 
					                NULL);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
| 
						 | 
					@ -2243,8 +2232,6 @@ void SubstitutionGoal::tryToRun()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            logPipe.readSide.close();
 | 
					            logPipe.readSide.close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* !!! close other handles */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            commonChildInit(logPipe);
 | 
					            commonChildInit(logPipe);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Fill in the arguments. */
 | 
					            /* Fill in the arguments. */
 | 
				
			||||||
| 
						 | 
					@ -2286,7 +2273,6 @@ void SubstitutionGoal::finished()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Since we got an EOF on the logger pipe, the substitute is
 | 
					    /* Since we got an EOF on the logger pipe, the substitute is
 | 
				
			||||||
       presumed to have terminated.  */
 | 
					       presumed to have terminated.  */
 | 
				
			||||||
    /* !!! this could block! */
 | 
					 | 
				
			||||||
    pid_t savedPid = pid;
 | 
					    pid_t savedPid = pid;
 | 
				
			||||||
    int status = pid.wait(true);
 | 
					    int status = pid.wait(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2469,12 +2455,6 @@ bool Worker::canBuildMore()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Worker::canPostpone()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return children.size() != 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Worker::childStarted(GoalPtr goal,
 | 
					void Worker::childStarted(GoalPtr goal,
 | 
				
			||||||
    pid_t pid, const set<int> & fds, bool inBuildSlot)
 | 
					    pid_t pid, const set<int> & fds, bool inBuildSlot)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -2527,16 +2507,6 @@ void Worker::waitForBuildSlot(GoalPtr goal)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Worker::waitForChildTermination(GoalPtr goal)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    debug("wait for child termination");
 | 
					 | 
				
			||||||
    if (children.size() == 0)
 | 
					 | 
				
			||||||
        throw Error("waiting for a build slot, yet there are no running children - "
 | 
					 | 
				
			||||||
            "maybe the build hook gave an inappropriate `postpone' reply?");
 | 
					 | 
				
			||||||
    wantingToBuild.insert(goal);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Worker::waitForAnyGoal(GoalPtr goal)
 | 
					void Worker::waitForAnyGoal(GoalPtr goal)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    debug("wait for any goal");
 | 
					    debug("wait for any goal");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue