Add scheduling algorithm for KaaS jobs
Change-Id: I95bde1f33f9450919c5f876ecce494e38859c88d
diff --git a/src/com/mirantis/mk/KaasUtils.groovy b/src/com/mirantis/mk/KaasUtils.groovy
index 967eaa1..b496e6f 100644
--- a/src/com/mirantis/mk/KaasUtils.groovy
+++ b/src/com/mirantis/mk/KaasUtils.groovy
@@ -1225,3 +1225,49 @@
}
return cmdParams
}
+
+/**
+ * custom scheduling algorithm
+ * it ensures that builds of the same job are distributed as much as possible between different nodes
+ * @param label (string) desired node label
+ * @return: (string) node name
+ */
+def schedule (label='docker') {
+ def common = new com.mirantis.mk.Common()
+ def freeNodes = []
+ def nodesMap = [:]
+
+ // filter nodes with the specified label and at least one free executor
+ timeout(time: 30, unit: 'MINUTES') {
+ while (!freeNodes) {
+ freeNodes = jenkins.model.Jenkins.instance.computers.findAll { node ->
+ label in node.getAssignedLabels().collect { it.name } &&
+ node.isPartiallyIdle()
+ }
+ if (!freeNodes) {
+ echo 'No nodes available for scheduling, retrying...'
+ sleep 30
+ }
+ }
+ }
+
+ // generate a map of nodes matching other criteria
+ for (node in freeNodes) {
+ // sameJobExecutors is the number of executors running the same job as the calling one
+ sameJobExecutors = node.getExecutors() // get all executors
+ .collect { executor -> executor.getCurrentExecutable() } // get running "threads"
+ .collect { thread -> thread?.displayName } // filter job names from threads
+ .minus(null) // null = empty executors, remove them from the list
+ .findAll { it.contains(env.JOB_NAME) } // filter the same jobs as the calling one
+ .size()
+
+ // calculate busy executors, we don't want to count "sameJobExecutors" twice
+ totalBusyExecutors = node.countBusy() - sameJobExecutors
+ // generate the final map which contains nodes matching criteria with their load score
+ // builds of the same jobs have x10 score, all others x1
+ nodesMap += ["${node.getName()}" : sameJobExecutors * 10 + totalBusyExecutors]
+ }
+
+ // return the least loaded node
+ return common.SortMapByValueAsc(nodesMap).collect { it.key }[0]
+}