@Override @GuardedBy("hudson.model.Queue.lock") public long check(final SlaveComputer c) { if (c.isOffline() && c.isLaunchSupported()) { final HashMap<Computer, Integer> availableComputers = new HashMap<Computer, Integer>(); for (Computer o : Jenkins.getInstance().getComputers()) { if ((o.isOnline() || o.isConnecting()) && o.isPartiallyIdle() && o.isAcceptingTasks()) { final int idleExecutors = o.countIdle(); if (idleExecutors > 0) availableComputers.put(o, idleExecutors); } } boolean needComputer = false; long demandMilliseconds = 0; for (Queue.BuildableItem item : Queue.getInstance().getBuildableItems()) { // can any of the currently idle executors take this task? // assume the answer is no until we can find such an executor boolean needExecutor = true; for (Computer o : Collections.unmodifiableSet(availableComputers.keySet())) { Node otherNode = o.getNode(); if (otherNode != null && otherNode.canTake(item) == null) { needExecutor = false; final int availableExecutors = availableComputers.remove(o); if (availableExecutors > 1) { availableComputers.put(o, availableExecutors - 1); } else { availableComputers.remove(o); } break; } } // this 'item' cannot be built by any of the existing idle nodes, but it can be built by // 'c' Node checkedNode = c.getNode(); if (needExecutor && checkedNode != null && checkedNode.canTake(item) == null) { demandMilliseconds = System.currentTimeMillis() - item.buildableStartMilliseconds; needComputer = demandMilliseconds > inDemandDelay * 1000 * 60 /*MINS->MILLIS*/; break; } } if (needComputer) { // we've been in demand for long enough logger.log( Level.INFO, "Launching computer {0} as it has been in demand for {1}", new Object[] {c.getName(), Util.getTimeSpanString(demandMilliseconds)}); c.connect(false); } } else if (c.isIdle()) { final long idleMilliseconds = System.currentTimeMillis() - c.getIdleStartMilliseconds(); if (idleMilliseconds > idleDelay * 1000 * 60 /*MINS->MILLIS*/) { // we've been idle for long enough logger.log( Level.INFO, "Disconnecting computer {0} as it has been idle for {1}", new Object[] {c.getName(), Util.getTimeSpanString(idleMilliseconds)}); c.disconnect(new OfflineCause.IdleOfflineCause()); } else { // no point revisiting until we can be confident we will be idle return TimeUnit.MILLISECONDS.toMinutes( TimeUnit.MINUTES.toMillis(idleDelay) - idleMilliseconds); } } return 1; }
@GuardedBy("hudson.model.Queue.lock") public long check(SlaveComputer c) { if (c.isOffline() && !c.isConnecting() && c.isLaunchSupported()) c.tryReconnect(); return 1; }