Dagster传感器中能否重新运行同run_key的RunRequest?
解决方案:失效原RunRequest并重新触发同文件处理
完全可以实现这个需求,核心是利用Dagster的run_key特性结合传感器的状态跟踪,来识别失败的作业并重新触发相同文件的处理请求。
具体实现思路与步骤
1. 跟踪文件的作业运行状态
在传感器里维护每个文件路径的处理状态,你可以选择两种方式存储状态:
- 轻量场景用
context.cursor:把已处理/处理中/处理失败的文件路径用分隔符拼接成字符串存在cursor里 - 复杂场景用外部存储:比如本地文件、数据库表,记录每个文件对应的最新作业状态(未处理/处理中/失败/成功)
2. 识别失败作业并重新生成RunRequest
Dagster允许用相同的run_key提交新的RunRequest,只要该run_key对应的上一次作业是失败状态,新请求就会被正常触发。具体逻辑:
- 每次传感器扫描时,查询当前文件路径对应的最新作业记录
- 如果最新作业状态是失败,直接生成带相同
run_key的RunRequest - 如果作业还在运行中,暂时跳过,避免重复触发
- 如果作业成功,标记为已完成不再处理
3. 传感器代码示例
from dagster import SensorDefinition, SensorResult, RunRequest, RunStatusFilter, RunStatus def file_system_sensor(context): # 自定义方法:扫描文件系统中的新文件/待重试文件 target_files = scan_target_files() # 从cursor读取已跟踪的文件,初始为空列表 tracked_files = context.cursor.split(",") if context.cursor else [] updated_tracked = [] run_requests = [] for file_path in target_files: # 查询当前文件对应的最新作业记录 latest_runs = context.instance.get_runs( filters=RunStatusFilter(run_key=file_path), limit=1 ) latest_run = latest_runs[0] if latest_runs else None if not latest_run: # 从未触发过处理,生成RunRequest run_requests.append(RunRequest( run_key=file_path, run_config={"ops": {"process_file": {"config": {"file_path": file_path}}}} )) updated_tracked.append(file_path) elif latest_run.status == RunStatus.FAILURE: # 上一次处理失败,重新触发 run_requests.append(RunRequest( run_key=file_path, run_config={"ops": {"process_file": {"config": {"file_path": file_path}}}} )) updated_tracked.append(file_path) elif latest_run.status == RunStatus.SUCCESS: # 处理成功,跳过 updated_tracked.append(file_path) else: # 作业正在运行中,暂时跳过 updated_tracked.append(file_path) # 更新cursor,保存跟踪状态 return SensorResult( run_requests=run_requests, cursor=",".join(updated_tracked) ) # 绑定你的资产作业 file_sensor_def = SensorDefinition( name="file_trigger_sensor", job=your_asset_processing_job, evaluation_fn=file_system_sensor )
4. 关键注意事项
- run_key的复用逻辑:相同
run_key的RunRequest,只有当上一次作业处于失败状态时才会被触发;如果作业还在运行,新请求会被自动忽略,避免重复执行。 - 避免无限重试:建议在状态里加入重试次数统计,达到设定的最大次数后,停止生成RunRequest,标记为处理失败,防止死循环。
- 状态存储扩展性:如果文件数量多或者需要跨实例共享状态,别用
context.cursor(有长度限制),换成数据库表来记录状态更可靠。
内容的提问来源于stack exchange,提问作者ted
相关产品推荐
相关产品推荐

