package loop import ( "context" "git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/trace" ) // span 在配置了 Tracer 时启动一个给定 kind 的具名 span,否则 // 返回 nil 空操作 span。返回的 context 把该 span 作为当前 span 携带, // 使嵌套 span 作为子节点串链。配置了 FlowPublisher 时, // span 的 flow owner(子代理 Run 取分支父级,否则取 Run 自身的 // session,两者都经 ctx 传递)会被打为 prop,并立即发布一个 // 运行中的占位节点,使 flow 图能显示在途工作。 func (l *Loop) span(ctx context.Context, name string, kind trace.SpanKind) (context.Context, *trace.Span) { if l.tracer == nil { return ctx, nil } sctx, sp := l.tracer.StartSpan(ctx, name, kind) if sid := flowOwner(ctx, loopSession(ctx)); sid != "" { _ = sp.SetProp("session", sid) if l.flow != nil { l.flow.SpanStarted(sid, sp) } } return sctx, sp } // finishSpan 以给定状态关闭 span,忽略 nil span。span 关闭 // (不可变)后,完成记录被并入 flow 图并 // 发布,把该节点翻转为最终状态。 func (l *Loop) finishSpan(sp *trace.Span, status trace.SpanStatus) { if sp == nil { return } sp.Finish(status) if l.flow != nil { if sid, ok := sp.Props["session"].(string); ok && sid != "" { l.flow.SpanFinished(sid, sp) } } } // spanProp 给 span 附加一个结构化属性,忽略 nil span 以及 // 关闭后变更所返回的错误。 func (l *Loop) spanProp(sp *trace.Span, key string, value any) { if sp == nil { return } _ = sp.SetProp(key, value) }