Python多进程推送Helm Chart时单个进程失败如何终止整个构建
解决方案
问题原因
你之前尝试的方案存在两个核心错误:
executor.submit()返回的是concurrent.futures.Future对象,不是任务的实际执行结果,直接和0比较永远不成立- 提交任务后立刻判断结果并退出,不会等待剩余任务执行完成
修改思路
- 改造子进程执行函数
slave,不再直接调用sys.exit(),而是返回布尔值标记执行成功/失败,所有异常场景统一返回失败状态 - 主进程收集所有提交任务的
Future对象,等待全部任务执行完成后再统一校验结果 - 只要有任意一个任务执行失败,主进程最终返回非0退出码,标记整个构建失败
额外注意:你原有代码中helm create命令拼接缺少空格,会直接导致命令执行失败,需要同步修正
具体实现
1. 调整slave函数逻辑
def slave(path1, path2, target): # 子进程单独配置日志,不需要传主进程的logger对象,避免跨进程日志异常 logging.basicConfig(level=logging.DEBUG, format="%(levelname)s:%(processName)s:%(message)s") try: # 创建临时目录 os.makedirs(target, exist_ok=True) logging.info("Create folder %s", target) logging.info("Copying files to %s", target) shutil.copy(path1, target) shutil.copy(path2, target) # 执行artifactory登录 result = os.system("<artifactory login command>") if result != 0: logging.error("Artifactory login failed, exit code: %s", result) return False # 执行helm构建推送,注意命令中间补全空格 res = os.system(f"helm create {target} --docker-registry dockerio.com/airlines_solutions/ -i") if res != 0: logging.error("Helm chart build failed, exit code: %s", res) return False # 所有步骤执行成功 return True except Exception as e: logging.error("Task execution failed: %s", traceback.format_exc()) return False
2. 调整主进程结果校验逻辑
def main(): logging.basicConfig(level=logging.INFO) processed = {} with open('example.json', 'r') as f: data = json.load(f) for value in data.items(): zip_file = "" yaml_file = "" for line in value[1]: if line.endswith('.zip'): zip_file = line elif line.endswith('.yaml'): yaml_file = line processed[zip_file] = yaml_file futures = [] with concurrent.futures.ProcessPoolExecutor() as executor: for id, (path2, path1) in enumerate(processed.items(), 1): target = path.join("/tmp", "dir" + str(id)) # 提交任务,存储future对象 futures.append(executor.submit(slave, path1, path2, target)) # 等待所有任务执行完成,统计失败数 failed_count = 0 for future in futures: try: # 获取任务执行结果,超时时间可按需配置 success = future.result() if not success: failed_count += 1 except Exception as e: logging.error("Task throw exception: %s", e) failed_count += 1 # 只要有失败任务,标记整个构建失败 if failed_count > 0: logging.error(f"Total {failed_count} tasks failed, build failed") sys.exit(1) else: logging.info("All tasks executed successfully, build success") sys.exit(0)
补充说明
os.system返回的退出码是16位整数,高8位是实际的程序退出码,如果你需要判断原始退出码可以用result >> 8获取- 该实现会等待所有任务全部执行完成后再统一返回结果,不会提前终止剩余任务的执行
内容的提问来源于stack exchange,提问作者voltas
相关产品推荐
相关产品推荐

