Flask 应用程序中的单个 apscheduler 实例
Single apscheduler instance in Flask application
设置:
- Flask 应用程序 运行通过 wsgi 在 Apache 的 httpd 中运行
- 具有 25 个线程的单个 wsgi 进程:
WSGIDaemonProcess myapp threads=25
- apscheduler 到 运行 个作业(发送电子邮件)
- RethinkDB 作为作业存储的后端
我试图通过阻止 apscheduler 的多个实例启动来阻止 apscheduler 运行多次执行同一个作业。目前我正在使用以下代码来确保调度程序只启动一次:
if 'SCHEDULER' not in app.config or app.config['SCHEDULER'] is None:
logger.info("Configuring scheduler")
app.config['SCHEDULER'] = scheduler.configure()
但是,当我查看我的日志时,我看到调度程序启动了两次:
[07:07:56.796001 pid 24778 INFO] main.py 57:Configuring scheduler
[07:07:56.807977 pid 24778 INFO] base.py 132:Scheduler started
[07:07:56.812253 pid 24778 DEBUG] base.py 795:Looking for jobs to run
[07:07:56.818019 pid 24778 DEBUG] base.py 840:Next wakeup is due at-10-14 11:30:00+00:00 (in 1323.187678 seconds)
[07:07:57.919869 pid 24777 INFO] main.py 57:Configuring scheduler
[07:07:57.930654 pid 24777 INFO] base.py 132:Scheduler started
[07:07:57.935212 pid 24777 DEBUG] base.py 795:Looking for jobs to run
[07:07:57.939795 pid 24777 DEBUG] base.py 840:Next wakeup is due at-10-14 11:30:00+00:00 (in 1322.064753 seconds)
从 pid 可以看出,有两个进程正在启动 somewhere/somehow。我怎样才能防止这种情况发生? httpd中这个配置在哪里?
假设我确实想要两个进程 运行ning,我可以使用 flock
来防止 apscheduler 启动两次。但是,这不会起作用,因为未启动 apscheduler 的进程将无法 add/remove 作业,因为 app.config['SCHEDULER']
设置供该进程使用。
configure/setup 具有多个进程的 Flask web 应用程序可以 add/remove 作业的最佳方法是什么,同时防止调度程序多次 运行 执行作业?
我最终决定使用基于文件的锁来确保任务不会 运行 两次:
def get_lock(name):
fd = open('/tmp/' + name, 'w')
try:
flock(fd, LOCK_EX | LOCK_NB) # open for exclusive locking
return fd
except IOError as e:
logger.warn('Could not get the lock for ' + str(name))
fd.close()
return None
def release_lock(fd):
sleep(2) # extend the time a bit longer in the hopes that it blocks the other proc
flock(fd, LOCK_UN)
fd.close()
这有点乱,但似乎有效...
设置:
- Flask 应用程序 运行通过 wsgi 在 Apache 的 httpd 中运行
- 具有 25 个线程的单个 wsgi 进程:
WSGIDaemonProcess myapp threads=25
- apscheduler 到 运行 个作业(发送电子邮件)
- RethinkDB 作为作业存储的后端
我试图通过阻止 apscheduler 的多个实例启动来阻止 apscheduler 运行多次执行同一个作业。目前我正在使用以下代码来确保调度程序只启动一次:
if 'SCHEDULER' not in app.config or app.config['SCHEDULER'] is None:
logger.info("Configuring scheduler")
app.config['SCHEDULER'] = scheduler.configure()
但是,当我查看我的日志时,我看到调度程序启动了两次:
[07:07:56.796001 pid 24778 INFO] main.py 57:Configuring scheduler
[07:07:56.807977 pid 24778 INFO] base.py 132:Scheduler started
[07:07:56.812253 pid 24778 DEBUG] base.py 795:Looking for jobs to run
[07:07:56.818019 pid 24778 DEBUG] base.py 840:Next wakeup is due at-10-14 11:30:00+00:00 (in 1323.187678 seconds)
[07:07:57.919869 pid 24777 INFO] main.py 57:Configuring scheduler
[07:07:57.930654 pid 24777 INFO] base.py 132:Scheduler started
[07:07:57.935212 pid 24777 DEBUG] base.py 795:Looking for jobs to run
[07:07:57.939795 pid 24777 DEBUG] base.py 840:Next wakeup is due at-10-14 11:30:00+00:00 (in 1322.064753 seconds)
从 pid 可以看出,有两个进程正在启动 somewhere/somehow。我怎样才能防止这种情况发生? httpd中这个配置在哪里?
假设我确实想要两个进程 运行ning,我可以使用 flock
来防止 apscheduler 启动两次。但是,这不会起作用,因为未启动 apscheduler 的进程将无法 add/remove 作业,因为 app.config['SCHEDULER']
设置供该进程使用。
configure/setup 具有多个进程的 Flask web 应用程序可以 add/remove 作业的最佳方法是什么,同时防止调度程序多次 运行 执行作业?
我最终决定使用基于文件的锁来确保任务不会 运行 两次:
def get_lock(name):
fd = open('/tmp/' + name, 'w')
try:
flock(fd, LOCK_EX | LOCK_NB) # open for exclusive locking
return fd
except IOError as e:
logger.warn('Could not get the lock for ' + str(name))
fd.close()
return None
def release_lock(fd):
sleep(2) # extend the time a bit longer in the hopes that it blocks the other proc
flock(fd, LOCK_UN)
fd.close()
这有点乱,但似乎有效...