This repository has been archived by the owner on Mar 31, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add pluggable ENI fitness evaluator (#170) * Make the number of threads in TaskScheduler configurable
- Loading branch information
tbak
authored
Feb 6, 2018
1 parent
30b1874
commit 76902c7
Showing
10 changed files
with
351 additions
and
124 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
fenzo-core/src/main/java/com/netflix/fenzo/CompositeSchedulingEventListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package com.netflix.fenzo; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.function.Consumer; | ||
|
||
class CompositeSchedulingEventListener implements SchedulingEventListener { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(CompositeSchedulingEventListener.class); | ||
|
||
private final List<SchedulingEventListener> listeners; | ||
|
||
private CompositeSchedulingEventListener(Collection<SchedulingEventListener> listeners) { | ||
this.listeners = new ArrayList<>(listeners); | ||
} | ||
|
||
@Override | ||
public void onScheduleStart() { | ||
safely(SchedulingEventListener::onScheduleStart); | ||
} | ||
|
||
@Override | ||
public void onAssignment(TaskAssignmentResult taskAssignmentResult) { | ||
safely(listener -> listener.onAssignment(taskAssignmentResult)); | ||
} | ||
|
||
@Override | ||
public void onScheduleFinish() { | ||
safely(SchedulingEventListener::onScheduleFinish); | ||
} | ||
|
||
private void safely(Consumer<SchedulingEventListener> action) { | ||
listeners.forEach(listener -> { | ||
try { | ||
action.accept(listener); | ||
} catch (Exception e) { | ||
logger.warn("Scheduling event dispatching error: {} -> {}", listener.getClass().getSimpleName(), e.getMessage()); | ||
if (logger.isDebugEnabled()) { | ||
logger.debug("Details", e); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
static SchedulingEventListener of(Collection<SchedulingEventListener> listeners) { | ||
if (listeners.isEmpty()) { | ||
return NoOpSchedulingEventListener.INSTANCE; | ||
} | ||
return new CompositeSchedulingEventListener(listeners); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
.../src/main/java/com/netflix/fenzo/DefaultPreferentialNamedConsumableResourceEvaluator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.netflix.fenzo; | ||
|
||
/** | ||
* Default {@link PreferentialNamedConsumableResourceEvaluator} implementation. | ||
*/ | ||
public class DefaultPreferentialNamedConsumableResourceEvaluator implements PreferentialNamedConsumableResourceEvaluator { | ||
|
||
public static final PreferentialNamedConsumableResourceEvaluator INSTANCE = new DefaultPreferentialNamedConsumableResourceEvaluator(); | ||
|
||
@Override | ||
public double evaluateIdle(String hostname, String resourceName, int index, double subResourcesNeeded, double subResourcesLimit) { | ||
// unassigned: 0.0 indicates no fitness, so return 0.5, which is less than the case of assigned with 0 sub-resources | ||
return 0.5 / (subResourcesLimit + 1); | ||
} | ||
|
||
@Override | ||
public double evaluate(String hostname, String resourceName, int index, double subResourcesNeeded, double subResourcesUsed, double subResourcesLimit) { | ||
return Math.min(1.0, (subResourcesUsed + subResourcesNeeded + 1.0) / (subResourcesLimit + 1)); | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
fenzo-core/src/main/java/com/netflix/fenzo/NoOpSchedulingEventListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.netflix.fenzo; | ||
|
||
class NoOpSchedulingEventListener implements SchedulingEventListener { | ||
|
||
static final SchedulingEventListener INSTANCE = new NoOpSchedulingEventListener(); | ||
|
||
@Override | ||
public void onScheduleStart() { | ||
} | ||
|
||
@Override | ||
public void onAssignment(TaskAssignmentResult taskAssignmentResult) { | ||
} | ||
|
||
@Override | ||
public void onScheduleFinish() { | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
fenzo-core/src/main/java/com/netflix/fenzo/PreferentialNamedConsumableResourceEvaluator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package com.netflix.fenzo; | ||
|
||
import com.netflix.fenzo.PreferentialNamedConsumableResourceSet.PreferentialNamedConsumableResource; | ||
|
||
/** | ||
* Evaluator for {@link PreferentialNamedConsumableResource} selection process. Given an agent with matching | ||
* ENI slot (either empty or with a matching name), this evaluator computes the fitness score. | ||
* A custom implementation can provide fitness calculators augmented with additional information not available to | ||
* Fenzo for making best placement decision. | ||
* | ||
* <h1>Example</h1> | ||
* {@link PreferentialNamedConsumableResource} can be used to model AWS ENI interfaces together with IP and security | ||
* group assignments. To minimize number of AWS API calls and to improve efficiency, it is beneficial to place a task | ||
* on an agent which has ENI profile with matching security group profile so the ENI can be reused. Or if a task | ||
* is terminated, but agent releases its resources lazily, they can be reused by another task with a matching profile. | ||
*/ | ||
public interface PreferentialNamedConsumableResourceEvaluator { | ||
|
||
/** | ||
* Provide fitness score for an idle consumable resource. | ||
* | ||
* @param hostname hostname of an agent | ||
* @param resourceName name to be associated with a resource with the given index | ||
* @param index a consumable resource index | ||
* @param subResourcesNeeded an amount of sub-resources required by a scheduled task | ||
* @param subResourcesLimit a total amount of sub-resources available | ||
* @return fitness score | ||
*/ | ||
double evaluateIdle(String hostname, String resourceName, int index, double subResourcesNeeded, double subResourcesLimit); | ||
|
||
/** | ||
* Provide fitness score for a consumable resource that is already associated with some tasks. These tasks and | ||
* the current one having profiles so can share the resource. | ||
* | ||
* @param hostname hostname of an agent | ||
* @param resourceName name associated with a resource with the given index | ||
* @param index a consumable resource index | ||
* @param subResourcesNeeded an amount of sub-resources required by a scheduled task | ||
* @param subResourcesUsed an amount of sub-resources already used by other tasks | ||
* @param subResourcesLimit a total amount of sub-resources available | ||
* @return fitness score | ||
*/ | ||
double evaluate(String hostname, String resourceName, int index, double subResourcesNeeded, double subResourcesUsed, double subResourcesLimit); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
fenzo-core/src/main/java/com/netflix/fenzo/SchedulingEventListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.netflix.fenzo; | ||
|
||
/** | ||
* A callback API providing notification about Fenzo task placement decisions during the scheduling process. | ||
*/ | ||
public interface SchedulingEventListener { | ||
|
||
/** | ||
* Called before a new scheduling iteration is started. | ||
*/ | ||
void onScheduleStart(); | ||
|
||
/** | ||
* Called when a new task placement decision is made (a task gets resources allocated on a server). | ||
* | ||
* @param taskAssignmentResult task assignment result | ||
*/ | ||
void onAssignment(TaskAssignmentResult taskAssignmentResult); | ||
|
||
/** | ||
* Called when the scheduling iteration completes. | ||
*/ | ||
void onScheduleFinish(); | ||
} |
Oops, something went wrong.