As described by https://yihui.org/en/2017/10/later-recursion/, It is possible to instruct R to execute a function periodically with a timed delay using the later::later package
As a minimal example, consider following main.R and Dockerfile:
# main.R:
timer <- function() {
print("repeat after 3 seconds")
later::later(timer, 3)
}
timer()
# Dockerfile
FROM rocker/r-base:4.1.2
RUN R -e "install.packages('later')"
COPY / /
ENTRYPOINT ["Rscript", "main.R"]
build with docker build -t r-timer and running the container with docker run r-timer makes the loop execute exactly once, after which the container exits. terminal output:
$ docker run r-timer
[1] "repeat after 3 seconds"
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS
aa1c33b39c2e r-timer "Rscript main.R" About a minute ago Exited (0) About a minute ago
my questions:
- Does using later::later mean the thread is suspended, which makes docker believe there is no running process and the container is thus stopped?
- How can I keep the container running and make R run continuously?
EDIT:
Thanks to @danlooo I learned about docker killing any background tasks when the container finishes the main thread. I adapted the Dockerfile to do a UNIX sleep on the main thread, pushing the Rscript thread to the background. To monitor the behaviour I added log4r to print lines to a file rather than using print(). I'm still seeing the same behaviour: when accessing the container and checking info.log, it only contains an entry for ONE execution.
library("log4r")
log_file <- "info.log"
log <- logger("INFO", appenders = file_appender(log_file))
info(log,"started logger")
timer <- function() {
info(log, "Repeat after 3 seconds")
later::later(timer, 3)
}
timer()
FROM rocker/r-base:4.1.2
RUN R -e "install.packages('later')"
RUN R -e "install.packages('log4r')"
COPY / /
CMD Rscript main.R & tail -f info.log