Wait for the completion of the command execution launched via the docker-java library

61 Views Asked by At

I have a docker-swarm stack with a number of services, one of which is a java application container that needs to launch a command in the shell of another container. The two services are deployed on the same machine, so the application can launch the command through the docker-java library. If I simply give commands whose execution is instantaneous (e.g., mkdir directory_name or rm -rf directory_name) the command is executed correctly. The problem is that the actual command takes quite a long time to process (no less than a few minutes), as data must be processed. After running the command in the other container, the java application has to clear the data that the other service has to process, so it needs to wait for the other service to complete processing before proceeding. Despite various modifications to try to synchronize the two services, the application never waits for the completion of the execution of the command in the other container, deleting the data before it has been processed. How can I modify the code so that the program waits for the end of the processing it launches in the other container?

String dockerSocket = "unix:///var/run/docker.sock";

DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
                .withDockerHost(dockerSocket)
                .build();

DockerClient dockerClient = DockerClientBuilder.getInstance(config).build();

List<Container> containers = dockerClient.listContainersCmd().withNameFilter(Collections.singleton("accumulo-master")).exec();

    try {
        logger.info("Trying to execute ingestion command");

        if (!containers.isEmpty()) {
            String containerID = containers.get(0).getId();
            logger.info("containerID: " + containerID);

            String[] command = { "/bin/bash", "-c", "command to execute" };

            ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(containerID)
                    .withCmd(command)
                    .exec();

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

            ExecStartResultCallback execStartResultCallback = new ExecStartResultCallback(outputStream, System.err) {
                @Override
                public void onComplete() {
                    logger.info("Results");
                    logger.info(outputStream.toString());
                    try {
                        Thread.sleep(120000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            };

            dockerClient.execStartCmd(execCreateCmdResponse.getId())
                    .exec(execStartResultCallback).onComplete();

The only case where it works is with that try-catch block with the Thread.sleep(120000) instruction; which makes the program wait before continuing. However, since the duration of processing is variable, a fixed wait time cannot be put in place, so that try-catch block must be removed.

0

There are 0 best solutions below