TotalProgressListener Class — spring-boot Architecture
Architecture documentation for the TotalProgressListener class in TotalProgressListener.java from the spring-boot codebase.
Entity Profile
Source Code
buildpack/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/TotalProgressListener.java lines 36–132
public abstract class TotalProgressListener<E extends ImageProgressUpdateEvent> implements UpdateListener<E> {
private final Map<String, Layer> layers = new ConcurrentHashMap<>();
private final Consumer<TotalProgressEvent> consumer;
private final String[] trackedStatusKeys;
private boolean progressStarted;
/**
* Create a new {@link TotalProgressListener} that sends {@link TotalProgressEvent
* events} to the given consumer.
* @param consumer the consumer that receives {@link TotalProgressEvent progress
* events}
* @param trackedStatusKeys a list of status event keys to track the progress of
*/
protected TotalProgressListener(Consumer<TotalProgressEvent> consumer, String[] trackedStatusKeys) {
this.consumer = consumer;
this.trackedStatusKeys = trackedStatusKeys;
}
@Override
public void onStart() {
}
@Override
public void onUpdate(E event) {
if (event.getId() != null) {
this.layers.computeIfAbsent(event.getId(), (value) -> new Layer(this.trackedStatusKeys)).update(event);
}
this.progressStarted = this.progressStarted || event.getProgress() != null;
if (this.progressStarted) {
publish(0);
}
}
@Override
public void onFinish() {
this.layers.values().forEach(Layer::finish);
publish(100);
}
private void publish(int fallback) {
int count = 0;
int total = 0;
for (Layer layer : this.layers.values()) {
count++;
total += layer.getProgress();
}
TotalProgressEvent event = new TotalProgressEvent(
(count != 0) ? withinPercentageBounds(total / count) : fallback);
this.consumer.accept(event);
}
private static int withinPercentageBounds(int value) {
return (value < 0) ? 0 : Math.min(value, 100);
}
/**
* Progress for an individual layer.
*/
private static class Layer {
private final Map<String, Integer> progressByStatus = new HashMap<>();
Layer(String[] trackedStatusKeys) {
Arrays.stream(trackedStatusKeys).forEach((status) -> this.progressByStatus.put(status, 0));
}
void update(ImageProgressUpdateEvent event) {
String status = event.getStatus();
if (status == null) {
return;
}
if (event.getProgressDetail() != null && this.progressByStatus.containsKey(status)) {
int current = this.progressByStatus.get(status);
this.progressByStatus.put(status, updateProgress(current, event.getProgressDetail()));
}
}
private int updateProgress(int current, ProgressDetail detail) {
return Math.max(detail.asPercentage(), current);
}
void finish() {
this.progressByStatus.keySet().forEach((key) -> this.progressByStatus.put(key, 100));
}
int getProgress() {
return withinPercentageBounds((this.progressByStatus.values().stream().mapToInt(Integer::intValue).sum())
/ this.progressByStatus.size());
}
}
}
Source
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free