Why does my cron(tinycron) execute a command twice sometimes?

Viewed 155

I'm using tinycron instead of cron, because of some security issues.

I tested with a simple python file.

python.py:

import time
print(time.ctime())

Dockerfile:

FROM MyBaseImage:Centos7

USER root

RUN yum -y update \
    && yum -y install python3 vim \
    && yum clean all \
    && rm -rf /var/cache/yum

RUN pip3 install requests

RUN localedef -c -i en_US -f UTF-8 en_US.UTF-8 && \
  localedef -c -i en_US -f UTF-8 en_US && \
  localedef -c -i ko_KR -f UTF-8 ko_KR.UTF-8 && \
  localedef -c -i ko_KR -f UTF-8 ko_KR

RUN echo "LANG=en_US.utf8" > /etc/locale.conf

# install tinycron
RUN curl -sLo tinycron https://github.com/bcicen/tinycron/releases/download/v0.3/tinycron-0.3-linux-amd64 \
    && chmod +x tinycron \
    && mv tinycron /usr/local/bin/

WORKDIR /app
COPY . /app

CMD /usr/local/bin/tinycron '*/5 * * * * * *' python3 /app/test.py

This should print time every five seconds.

However, it prints twice at times.

✗ docker run --rm -it --name=test tiny2
Tue Jul  7 12:02:15 2020
Tue Jul  7 12:02:20 2020
Tue Jul  7 12:02:25 2020
Tue Jul  7 12:02:30 2020
Tue Jul  7 12:02:34 2020 ###
Tue Jul  7 12:02:35 2020 ###
Tue Jul  7 12:02:40 2020
Tue Jul  7 12:02:45 2020
Tue Jul  7 12:02:50 2020
Tue Jul  7 12:02:55 2020
Tue Jul  7 12:03:00 2020
Tue Jul  7 12:03:04 2020 ###
Tue Jul  7 12:03:05 2020 ###

I checked in the container, and confirmed that there's only one cron process.

➜  ~ docker exec -it test /bin/bash
[root@ce614b03b559 app]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 12:02 pts/0    00:00:00 /usr/local/bin/tinycron */5 * * * * * * python3 /app/test.py
root        14     0  0 12:02 pts/1    00:00:00 /bin/bash
root        30    14  0 12:02 pts/1    00:00:00 ps -ef

What could cause this??

My real code have to run python codes(that send emails) every minute, and it is executed twice, too.

Any thought appreciated :)

1 Answers

This doesn't give the reason, but I solved somehow.

I used flock.

It seems that flock checks a lock file before starting a process, and prevents duplicated processes.

When I use the same test.py file, flock didn't help because test.py is so simple that 12:02:34 process ends immediately before 12:02:35 process starts.

But normally, a process takes a few seconds(at least for me).

So, I edited the test.py file, adding sleep as below:

import time
time.sleep(1)# wait for a second
print(time.ctime())

Test Result

  • CMD /usr/local/bin/tinycron '*/5 * * * * * *' python3 /app/test.py
✗ docker run --rm -it --name=test tiny2
Tue Jul  7 14:01:21 2020
Tue Jul  7 14:01:26 2020
Tue Jul  7 14:01:31 2020
Tue Jul  7 14:01:35 2020
Tue Jul  7 14:01:36 2020
Tue Jul  7 14:01:41 2020
Tue Jul  7 14:01:46 2020
Tue Jul  7 14:01:51 2020
Tue Jul  7 14:01:56 2020
Tue Jul  7 14:02:01 2020
Tue Jul  7 14:02:05 2020
Tue Jul  7 14:02:06 2020
Tue Jul  7 14:02:11 2020
  • CMD /usr/local/bin/tinycron '*/5 * * * * * *' flock -w 0 /mylock.lock python3 /app/test.py
✗ docker run --rm -it --name=test tiny2
Tue Jul  7 14:02:26 2020
Tue Jul  7 14:02:31 2020
[tinycron] job failed exit status 1
Tue Jul  7 14:02:35 2020
Tue Jul  7 14:02:41 2020
Tue Jul  7 14:02:46 2020
Tue Jul  7 14:02:51 2020
Tue Jul  7 14:02:56 2020
Tue Jul  7 14:03:01 2020
[tinycron] job failed exit status 1
Tue Jul  7 14:03:05 2020
Tue Jul  7 14:03:11 2020
Related