1616
1717package com .netflix .fenzo ;
1818
19+ import com .netflix .fenzo .common .ThreadFactoryBuilder ;
1920import com .netflix .fenzo .plugins .NoOpScaleDownOrderEvaluator ;
2021import com .netflix .fenzo .queues .Assignable ;
2122import com .netflix .fenzo .queues .QueuableTask ;
3435import java .util .concurrent .ExecutorService ;
3536import java .util .concurrent .Executors ;
3637import java .util .concurrent .Future ;
38+ import java .util .concurrent .ThreadFactory ;
3739import java .util .concurrent .atomic .AtomicBoolean ;
3840import java .util .concurrent .atomic .AtomicInteger ;
41+ import java .util .function .Supplier ;
3942import java .util .stream .Collectors ;
4043
4144/**
@@ -103,6 +106,7 @@ public Boolean call(Double f) {
103106 private boolean singleOfferMode =false ;
104107 private final List <SchedulingEventListener > schedulingEventListeners = new ArrayList <>();
105108 private int maxConcurrent = Runtime .getRuntime ().availableProcessors ();
109+ private Supplier <Long > taskBatchSizeSupplier = () -> Long .MAX_VALUE ;
106110
107111 /**
108112 * (Required) Call this method to establish a method that your task scheduler will call to notify you
@@ -442,6 +446,20 @@ public Builder withMaxConcurrent(int maxConcurrent) {
442446 return this ;
443447 }
444448
449+ /**
450+ * Use the given supplier to determine how many successful tasks should be evaluated in the next scheduling iteration. This
451+ * can be used to dynamically change how many successful task evaluations are done in order to increase/reduce the scheduling iteration
452+ * duration. The default supplier implementation will return {@link Long#MAX_VALUE} such that all tasks will be
453+ * evaluated.
454+ *
455+ * @param taskBatchSizeSupplier the supplier that returns the task batch size for the next scheduling iteration.
456+ * @return this same {@code Builder}, suitable for further chaining or to build the {@link TaskSchedulingService}.
457+ */
458+ public Builder withTaskBatchSizeSupplier (Supplier <Long > taskBatchSizeSupplier ) {
459+ this .taskBatchSizeSupplier = taskBatchSizeSupplier ;
460+ return this ;
461+ }
462+
445463 /**
446464 * Creates a {@link TaskScheduler} based on the various builder methods you have chained.
447465 *
@@ -497,7 +515,8 @@ private TaskScheduler(Builder builder) {
497515 throw new IllegalArgumentException ("Lease reject action must be non-null" );
498516 this .builder = builder ;
499517 this .maxConcurrent = builder .maxConcurrent ;
500- this .executorService = Executors .newFixedThreadPool (maxConcurrent );
518+ ThreadFactory threadFactory = ThreadFactoryBuilder .newBuilder ().withNameFormat ("fenzo-worker-%d" ).build ();
519+ this .executorService = Executors .newFixedThreadPool (maxConcurrent , threadFactory );
501520 this .stateMonitor = new StateMonitor ();
502521 this .schedulingEventListener = CompositeSchedulingEventListener .of (builder .schedulingEventListeners );
503522 taskTracker = new TaskTracker ();
@@ -795,6 +814,8 @@ private SchedulingResult doSchedule(
795814 Set <TaskRequest > failedTasksForAutoScaler = new HashSet <>();
796815 Map <String , VMAssignmentResult > resultMap = new HashMap <>(avms .size ());
797816 final SchedulingResult schedulingResult = new SchedulingResult (resultMap );
817+ long taskBatchSize = builder .taskBatchSizeSupplier .get ();
818+ long tasksIterationCount = 0 ;
798819 if (avms .isEmpty ()) {
799820 while (true ) {
800821 final Assignable <? extends TaskRequest > taskOrFailure = taskIterator .next ();
@@ -806,6 +827,9 @@ private SchedulingResult doSchedule(
806827 schedulingEventListener .onScheduleStart ();
807828 try {
808829 while (true ) {
830+ if (tasksIterationCount >= taskBatchSize ) {
831+ break ;
832+ }
809833 final Assignable <? extends TaskRequest > taskOrFailure = taskIterator .next ();
810834 if (logger .isDebugEnabled ())
811835 logger .debug ("TaskSched: task=" + (taskOrFailure == null ? "null" : taskOrFailure .getTask ().getId ()));
@@ -904,6 +928,7 @@ public EvalResult call() throws Exception {
904928 logger .debug ("Task {}: found successful assignment on host {}" , task .getId (),
905929 successfulResult .getHostname ());
906930 successfulResult .assignResult ();
931+ tasksIterationCount ++;
907932 failedTasksForAutoScaler .remove (task );
908933 schedulingEventListener .onAssignment (successfulResult );
909934 }
0 commit comments