推送真发送:webhook/slack 内置真实发送端 + worker 终态自动通知
此前订阅与分发框架都在,但分发端点传 sender=None, webhook/slack 永远报无 sender、从未真发过。本轮: - push:send_webhook/send_slack(标准库 urllib POST, 单次 10 秒超时,不重试,失败记 errors);sender=None 时用内置端,显式 sender 优先;webpush/apns/fcm 仍报 缺凭证(原因写明:webpush 需浏览器端三字段订阅与标准库 没有的 P-256 ECDH + AES-GCM;apns 需 HTTP/2;fcm 需 Firebase 服务账号,三者均无现成接收方,不造假发送) - worker:run_one 终态(completed/failed,缺 key 与仓库 失败两条早退路径也在内)后 best-effort 调分发,通知 失败只记日志、绝不影响任务状态;取消(interrupted) 不在事件集合里,不通知 - 测试:真实发送端 6 个(本地回环服务器)、worker 终态 通知 2 个,旧无 sender 断言按新语义改写
This commit is contained in:
1 parent
b7dace55b9
commit
fb3a311da8
7 files changed
+429
-29
No files matched your search
@@ -640,6 +640,34 @@ class Worker:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _notify_task_finished(self, task_id, project_id, event_type,
|
||||
error=None):
|
||||
"""任务终态推送:best-effort,绝不因通知失败影响任务状态。
|
||||
|
||||
只发 completed/failed(push.ALLOWED_PUSH_EVENTS 的子集;
|
||||
interrupted 不在事件集合里,取消不通知)。无订阅时
|
||||
dispatch 直接返回空 sent,不联网。同步发送、单次 10 秒
|
||||
超时:慢订阅会拖住 worker 循环最多几秒,换取投递结果
|
||||
可观测(失败记日志,不静默丢);后台队列是后续优化,
|
||||
不在本轮。
|
||||
"""
|
||||
try:
|
||||
from cloud.push import dispatch_event
|
||||
result = dispatch_event(
|
||||
self.db_path, event_type, project_id,
|
||||
{"task_id": task_id, "status": event_type,
|
||||
"executor": self._executor_name(), "error": error})
|
||||
if result.get("errors"):
|
||||
log_event(self.logger, "worker_notify_failed",
|
||||
task_id=task_id, project_id=project_id,
|
||||
status=event_type,
|
||||
message="notify errors: %s" % (result["errors"],))
|
||||
except Exception as exc: # noqa: BLE001 -- 通知失败绝不炸任务
|
||||
log_event(self.logger, "worker_notify_failed",
|
||||
task_id=task_id, project_id=project_id,
|
||||
status=event_type,
|
||||
message="notify exception: %s" % exc)
|
||||
|
||||
# -- 认领 ----------------------------------------------------------
|
||||
def _budget_exceeded(self):
|
||||
return budget_exceeded(self.usage_turns, self.max_turns,
|
||||
@@ -1346,6 +1374,8 @@ class Worker:
|
||||
self._audit(task["project_id"], "worker_missing_key", error)
|
||||
log_event(self.logger, "worker_missing_key", task_id=task_id,
|
||||
project_id=task["project_id"], status="failed")
|
||||
self._notify_task_finished(
|
||||
task_id, task["project_id"], "failed", error=error)
|
||||
return {"dispatched": True, "task_id": task_id,
|
||||
"host_name": self.executor._host_name(task)
|
||||
if hasattr(self.executor, "_host_name") else task_id,
|
||||
@@ -1365,6 +1395,8 @@ class Worker:
|
||||
self._audit(task["project_id"], "worker_repo_failed", repo_error)
|
||||
log_event(self.logger, "worker_repo_failed", task_id=task_id,
|
||||
project_id=task["project_id"], status="failed")
|
||||
self._notify_task_finished(
|
||||
task_id, task["project_id"], "failed", error=repo_error)
|
||||
return {"dispatched": True, "task_id": task_id,
|
||||
"host_name": self.executor._host_name(task)
|
||||
if hasattr(self.executor, "_host_name") else task_id,
|
||||
@@ -1537,6 +1569,9 @@ class Worker:
|
||||
else "worker_failed",
|
||||
task_id=task_id, project_id=task["project_id"],
|
||||
status=final)
|
||||
if final in ("completed", "failed"):
|
||||
self._notify_task_finished(
|
||||
task_id, task["project_id"], final, error=error)
|
||||
else:
|
||||
# 已被取消/回收:DB 状态以 interrupted 为准,不再
|
||||
# 补一条 worker_completed/failed 审计误导排查。
|
||||
|
||||
Reference in new issue
Block a user