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

Flask应用执行git pull线程时意外终止的问题求助

解决Git Pull线程异常导致Flask应用终止的问题

问题背景

我在运行Flask应用时,通过threading模块启动了一个定时线程,每2小时对指定Git仓库执行git pull操作。但遇到以下问题:

  • 当git pull出现冲突或其他异常时,Flask应用会意外终止
  • 即使Flask稳定运行数日,一旦git pull触发异常就会突然停止
  • 期望目标:git pull出错时不干扰Flask持续运行,且下一次定时任务能正常执行

问题分析

当前代码存在几个关键问题:

  • pre_tasks函数无异常捕获:git pull过程中出现冲突、权限不足、仓库路径错误等情况时,会抛出未处理的异常,直接终止定时线程,甚至可能影响整个进程
  • Flask线程启动方式错误:threading.Thread(target=hunter.run(...))会直接在主线程执行hunter.run()(括号是立即调用),导致Flask实际运行在主线程而非子线程
  • 缺失依赖导入:constants.py中使用sleep但未导入time模块,会触发NameError直接终止线程
  • Subprocess输出处理不当:communicate()返回的是bytes对象,直接logging.info(output)可能引发编码异常
  • 未检查Git命令执行结果:仅捕获输出但未判断git pull的返回码,无法明确操作是否成功

修复后的代码

主文件修复后代码

from flask import Flask, jsonify, request, make_response, Response
from constants import git_pull_thread
import threading
import logging

# 日志配置
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.INFO)

hunter = Flask(__name__)
health_status = True

def main():
    # 启动Git拉取线程
    git_pull_thread()

    # 启动Flask应用(正确的线程启动方式)
    try:
        logger.info("hunter service is running ")
        # 注意:target传入hunter.run函数,而非立即调用;参数用kwargs传入
        flask_thread = threading.Thread(
            target=hunter.run,
            kwargs={
                'ssl_context': ('path/to/cert.pem', 'path/to/key.pem'),
                'host': '0.0.0.0',
                'port': 5002,
                'debug': False  # 生产环境建议关闭debug模式,避免自动重启引发问题
            }
        )
        flask_thread.start()
    except Exception as e:
        logger.error(f"[-] Exception encountered while starting Flask: {e}")

if __name__ == '__main__':
    main()

constants.py修复后代码

import os
import subprocess
import threading
import logging
from time import sleep  # 导入缺失的sleep模块

# 日志配置
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.INFO)

GIT_PULL_INTERVAL = 7200  # 2小时(秒)

def pre_tasks():
    while True:
        directories = ["/hunter/tmp/policy", "/hunter/tmp/e2policy"]              
        for repo_dir in directories:
            logger.info(f"##### Updating repo: {repo_dir} #####")
            try:
                # 执行git pull命令
                cmd = ["git", "pull"]
                process = subprocess.Popen(
                    cmd,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,  # 捕获错误输出
                    cwd=repo_dir,
                    text=True  # 直接返回字符串,避免bytes解码问题
                )
                stdout, stderr = process.communicate()
                return_code = process.returncode

                if return_code == 0:
                    logger.info(f"Repo {repo_dir} updated successfully: {stdout.strip()}")
                else:
                    logger.error(f"Git pull failed for {repo_dir}, return code: {return_code}")
                    logger.error(f"Error output: {stderr.strip()}")

            except Exception as e:
                # 捕获所有可能的异常,确保线程不终止
                logger.error(f"Exception occurred while updating {repo_dir}: {str(e)}")
            
            # 每个仓库拉取后间隔2分钟,避免频繁操作
            sleep(120)
        
        # 所有仓库拉取完成后,等待2小时再执行下一轮
        sleep(GIT_PULL_INTERVAL)

def git_pull_thread():
    """启动定时Git拉取线程"""
    try:
        logger.info("Git pull thread started ")
        pull_thread = threading.Thread(target=pre_tasks, daemon=True)  # 设置为守护线程,随主进程退出
        pull_thread.start()
    except Exception as e:
        logger.error(f"[-] Exception encountered while starting git pull thread: {e}")

修复说明

  1. 异常捕获增强:在每个仓库的git pull操作外层添加try-except,确保单个仓库的错误不会终止整个定时线程,异常信息会被记录以便排查
  2. Flask线程启动修正:将target改为hunter.run函数对象,通过kwargs传递参数,确保Flask运行在子线程中
  3. 依赖补全:导入time.sleep模块,避免NameError
  4. Subprocess优化:
    • 捕获stderr错误输出,便于排查Git命令失败原因
    • 设置text=True直接获取字符串输出,避免bytes解码问题
    • 检查命令返回码,明确判断git pull是否成功
  5. 线程属性优化:将Git拉取线程设置为守护线程,确保主进程退出时线程自动终止

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 11:15:12