You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

mod_wsgi自动代码重载监控脚本触发RuntimeError问题求助

使用mod_wsgi实现代码自动重载时遇到RuntimeError问题

在用mod_wsgi实现代码变更自动重载时,运行官方文档提供的监控脚本出现RuntimeError,错误提示遍历sys.modules.values()时字典键发生变更。尝试文档中的示例代码也会触发相同错误,调整跟踪文件后,有时能完成一次重载,有时完全无法运行,不清楚问题原因及解决办法,特求助。

官方监控脚本代码

from __future__ import print_function

import os
import sys
import time
import signal
import threading
import atexit

try:
    import Queue as queue
except ImportError:
    import queue

_interval = 1.0
_times = {}
_files = []

_running = False
_queue = queue.Queue()
_lock = threading.Lock()

def _restart(path):
    _queue.put(True)
    prefix = 'monitor (pid=%d):' % os.getpid()
    print('%s Change detected to \'%s\'.' % (prefix, path), file=sys.stderr)
    print('%s Triggering process restart.' % prefix, file=sys.stderr)
    os.kill(os.getpid(), signal.SIGINT)

def _modified(path):
    try:
        # If path doesn't denote a file and were previously
        # tracking it, then it has been removed or the file type
        # has changed so force a restart. If not previously
        # tracking the file then we can ignore it as probably
        # pseudo reference such as when file extracted from a
        # collection of modules contained in a zip file.

        if not os.path.isfile(path):
            return path in _times

        # Check for when file last modified.

        mtime = os.stat(path).st_mtime
        if path not in _times:
            _times[path] = mtime

        # Force restart when modification time has changed, even
        # if time now older, as that could indicate older file
        # has been restored.

        if mtime != _times[path]:
            return True
    except:
        # If any exception occured, likely that file has been
        # been removed just before stat(), so force a restart.

        return True

    return False

def _monitor():
    while 1:
        # Check modification times on all files in sys.modules.
        for module in sys.modules.values():
            print(module)
            if not hasattr(module, '__file__'):
                continue
            path = getattr(module, '__file__')
            if not path:
                continue
            if os.path.splitext(path)[1] in ['.pyc', '.pyo', '.pyd']:
                path = path[:-1]
            if _modified(path):
                return _restart(path)

        # Check modification times on files which have
        # specifically been registered for monitoring.

        for path in _files:
            print(f'PATH: {path}')
            if _modified(path):
                return _restart(path)

        # Go to sleep for specified interval.

        try:
            return _queue.get(timeout=_interval)
        except:
            pass

_thread = threading.Thread(target=_monitor)
_thread.setDaemon(True)

def _exiting():
    try:
        _queue.put(True)
    except:
        pass
    _thread.join()

atexit.register(_exiting)

def track(path):
    if path not in _files:
        _files.append(path)

def start(interval=1.0):
    global _interval
    if interval < _interval:
        _interval = interval

    global _running
    _lock.acquire()
    if not _running:
        prefix = 'monitor (pid=%d):' % os.getpid()
        print('%s Starting change monitor.' % prefix, file=sys.stderr)
        _running = True
        _thread.start()
    _lock.release()

错误日志

[Thu Feb 23 18:46:27.482446 2023] [wsgi:error] [pid 11279] Exception in thread Thread-1 (_monitor):
[Thu Feb 23 18:46:27.482617 2023] [wsgi:error] [pid 11279] Traceback (most recent call last):
[Thu Feb 23 18:46:27.482635 2023] [wsgi:error] [pid 11279]   File "/usr/lib64/python3.10/threading.py", line 1016, in _bootstrap_inner
[Thu Feb 23 18:46:27.482983 2023] [wsgi:error] [pid 11279]     self.run()
[Thu Feb 23 18:46:27.483002 2023] [wsgi:error] [pid 11279]   File "/usr/lib64/python3.10/threading.py", line 953, in run
[Thu Feb 23 18:46:27.483162 2023] [wsgi:error] [pid 11279]     self._target(*self._args, **self._kwargs)
[Thu Feb 23 18:46:27.483177 2023] [wsgi:error] [pid 11279]   File "/srv/flask_app/flask_app/monitor.py", line 66, in _monitor
[Thu Feb 23 18:46:27.483239 2023] [wsgi:error] [pid 11279]     for module in sys.modules.values():
[Thu Feb 23 18:46:27.483263 2023] [wsgi:error] [pid 11279] RuntimeError: dictionary keys changed during iteration

调用监控脚本的代码

monitor.start(interval=1.0)
for root, dirs, files in os.walk(os.path.dirname(__file__), topdown=False):
   for name in files:
      monitor.track(os.path.join(root, name))

内容的提问来源于stack exchange,提问作者Jakke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 22:51:52