2016-05-14 5 views
1

Несмотря на проблемы с таймерами python, я обнаружил, что когда bottle.py запускается с «reloader = True», все функции таймера выполняются дважды подряд.Функции таймера Python выполняются дважды с флажком.pdf, когда reloader = True

Я пробовал это с несколькими различными способами вызова таймеров, и результат одинаковый во всех случаях (двойной запуск).

Пример кода:

#!/usr/bin/env python 

from threading import Timer 
from bottle import * 

# Short timer 
def short_time(): 
     t = Timer(1, short_time) 
     t.daemon = True 
     t.start() 
     print "Short Time..." 

# Long timer 
def long_time(): 
     t = Timer(5, long_time) 
     t.daemon = True 
     t.start() 
     print "Long Time..." 

# The App 
app = Bottle() 

@app.route('/status') 
def default(): 
     return "OK" 

#Run the app ----- 
if __name__ == '__main__': 

    # Start the short timer. 
    short_time() 

    # Start the long timer. 
    long_time() 

    # Run the app 
    # This interferes with the timers 
    run(app, host='0.0.0.0', port=8002, reloader=True) 

    #This one works as expected 
    #run(app, host='0.0.0.0', port=8002) #This works fine 

Выход с перегружатель включен:

Short Time... 
Short Time... 
Short Time... 
Short Time... 
Short Time... 
Short Time... 
Short Time... 
Short Time... 
Long Time... 
Short Time... 
Long Time... 
Short Time... 
Short Time... 
Short Time... 

Ожидаемый выход (без перегружателя):

Short Time... 
Short Time... 
Short Time... 
Short Time... 
Long Time... 
Short Time... 
Short Time... 
Short Time... 
Short Time... 
Short Time... 
Long Time... 
Short Time... 
Short Time... 

Любые идеи о как использовать rel oader, но предотвратить проблему с таймером?

+0

Связанный: [? Почему работает сам DEV сервер запустить КОЛБУ дважды] (https: // StackOverflow. com/q/25504149) –

ответ

2

Когда reloader=True установлен, процесс бутылки re-runs the script as a child process:

if reloader and not os.environ.get('BOTTLE_CHILD'): 
    import subprocess 
    lockfile = None 
    try: 
     fd, lockfile = tempfile.mkstemp(prefix='bottle.', suffix='.lock') 
     os.close(fd) # We only need this file to exist. We never write to it 
     while os.path.exists(lockfile): 
      args = [sys.executable] + sys.argv 
      environ = os.environ.copy() 
      environ['BOTTLE_CHILD'] = 'true' 
      environ['BOTTLE_LOCKFILE'] = lockfile 
      p = subprocess.Popen(args, env=environ) 

Ребенок затем перезапущен каждые interval секунд (по умолчанию 1).

Все, что запускается на верхнем уровне скрипта, запускается как при запуске сервера бутылок, так и при повторном запуске дочернего процесса.

Таким образом, как родительский , так и дочерний процесс выполняют таймеры независимо. Длительный таймер в дочернем процессе никогда не запускается, так как этот процесс убит до того, как за 5 секунд закончится, но короткий таймер может просто уйти до того, как родительский процесс убивает ребенка, чтобы запустить его снова.

Вы можете обнаружить, если вы находитесь в процессе ребенка путем проверки переменной в BOTTLE_CHILD среды:

import os 
if os.environ.get('BOTTLE_CHILD'): 
    # in the child process, do something special perhaps? 
    # this will be executed *each time the child is restarted* 
else: 
    # in the parent process, which restarts the child process 
+0

Спасибо Martijn. Я тестировал это, и он работает так, как ожидалось. – user3091850