Reduce number of CLI calls to improve startup time with devtools

Update `DockerComposeLifecycleManager` so that `docker ps` is
not called multiple times.

See gh-35435
pull/35555/head
Andy Wilkinson 2 years ago committed by Phillip Webb
parent b0c76c1f79
commit 6ad71c9b0c

@ -69,11 +69,6 @@ class DefaultDockerCompose implements DockerCompose {
return !this.cli.run(new DockerCliCommand.ComposeConfig()).services().isEmpty(); return !this.cli.run(new DockerCliCommand.ComposeConfig()).services().isEmpty();
} }
@Override
public boolean hasRunningServices() {
return runComposePs().stream().anyMatch(this::isRunning);
}
@Override @Override
public List<RunningService> getRunningServices() { public List<RunningService> getRunningServices() {
List<DockerCliComposePsResponse> runningPsResponses = runComposePs().stream().filter(this::isRunning).toList(); List<DockerCliComposePsResponse> runningPsResponses = runComposePs().stream().filter(this::isRunning).toList();

@ -73,15 +73,6 @@ public interface DockerCompose {
*/ */
boolean hasDefinedServices(); boolean hasDefinedServices();
/**
* Return if services defined in the {@link DockerComposeFile} for the active profile
* are running.
* @return {@code true} if services are running
* @see #hasDefinedServices()
* @see #getRunningServices()
*/
boolean hasRunningServices();
/** /**
* Return the running services for the active profile, or an empty list if no services * Return the running services for the active profile, or an empty list if no services
* are running. * are running.

@ -112,19 +112,21 @@ class DockerComposeLifecycleManager {
Start start = this.properties.getStart(); Start start = this.properties.getStart();
Stop stop = this.properties.getStop(); Stop stop = this.properties.getStop();
Wait wait = this.properties.getReadiness().getWait(); Wait wait = this.properties.getReadiness().getWait();
if (lifecycleManagement.shouldStart() && !dockerCompose.hasRunningServices()) { List<RunningService> runningServices = dockerCompose.getRunningServices();
if (lifecycleManagement.shouldStart() && runningServices.isEmpty()) {
start.getCommand().applyTo(dockerCompose, start.getLogLevel()); start.getCommand().applyTo(dockerCompose, start.getLogLevel());
runningServices = dockerCompose.getRunningServices();
wait = (wait != Wait.ONLY_IF_STARTED) ? wait : Wait.ALWAYS; wait = (wait != Wait.ONLY_IF_STARTED) ? wait : Wait.ALWAYS;
if (lifecycleManagement.shouldStop()) { if (lifecycleManagement.shouldStop()) {
this.shutdownHandlers.add(() -> stop.getCommand().applyTo(dockerCompose, stop.getTimeout())); this.shutdownHandlers.add(() -> stop.getCommand().applyTo(dockerCompose, stop.getTimeout()));
} }
} }
List<RunningService> runningServices = new ArrayList<>(dockerCompose.getRunningServices()); List<RunningService> relevantServices = new ArrayList<>(runningServices);
runningServices.removeIf(this::isIgnored); relevantServices.removeIf(this::isIgnored);
if (wait == Wait.ALWAYS || wait == null) { if (wait == Wait.ALWAYS || wait == null) {
this.serviceReadinessChecks.waitUntilReady(runningServices); this.serviceReadinessChecks.waitUntilReady(relevantServices);
} }
publishEvent(new DockerComposeServicesReadyEvent(this.applicationContext, runningServices)); publishEvent(new DockerComposeServicesReadyEvent(this.applicationContext, relevantServices));
} }
protected DockerComposeFile getComposeFile() { protected DockerComposeFile getComposeFile() {

@ -96,26 +96,6 @@ class DefaultDockerComposeTests {
assertThat(compose.hasDefinedServices()).isTrue(); assertThat(compose.hasDefinedServices()).isTrue();
} }
@Test
void hasRunningServicesWhenPsListsRunningServiceReturnsTrue() {
willReturn(List.of(new DockerCliComposePsResponse("id", "name", "image", "exited"),
new DockerCliComposePsResponse("id", "name", "image", "running")))
.given(this.cli)
.run(new DockerCliCommand.ComposePs());
DefaultDockerCompose compose = new DefaultDockerCompose(this.cli, HOST);
assertThat(compose.hasRunningServices()).isTrue();
}
@Test
void hasRunningServicesWhenPsListReturnsAllExitedReturnsFalse() {
willReturn(List.of(new DockerCliComposePsResponse("id", "name", "image", "exited"),
new DockerCliComposePsResponse("id", "name", "image", "running")))
.given(this.cli)
.run(new DockerCliCommand.ComposePs());
DefaultDockerCompose compose = new DefaultDockerCompose(this.cli, HOST);
assertThat(compose.hasRunningServices()).isTrue();
}
@Test @Test
void getRunningServicesReturnsServices() { void getRunningServicesReturnsServices() {
String id = "123"; String id = "123";

@ -351,7 +351,6 @@ class DockerComposeLifecycleManagerTests {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void setUpRunningServices(boolean started, Map<String, String> labels) { private void setUpRunningServices(boolean started, Map<String, String> labels) {
given(this.dockerCompose.hasDefinedServices()).willReturn(true); given(this.dockerCompose.hasDefinedServices()).willReturn(true);
given(this.dockerCompose.hasRunningServices()).willReturn(true);
RunningService runningService = mock(RunningService.class); RunningService runningService = mock(RunningService.class);
given(runningService.labels()).willReturn(labels); given(runningService.labels()).willReturn(labels);
this.runningServices = List.of(runningService); this.runningServices = List.of(runningService);

Loading…
Cancel
Save