public long check()

in core/src/main/java/hudson/slaves/RetentionStrategy.java [217:276]


        public long check(final SlaveComputer c) {
            if (c.isOffline() && c.isLaunchSupported()) {
                final HashMap<Computer, Integer> availableComputers = new HashMap<>();
                for (Computer o : Jenkins.get().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 > TimeUnit.MINUTES.toMillis(inDemandDelay);
                        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 > TimeUnit.MINUTES.toMillis(idleDelay)) {
                    // 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;
        }