event: Builder.Start returns a builder
Currently, Builder.Start's second return value is a function which,
when called, sends an End event with a copy of the Start event's
builder. This makes the common case
ctx, end := event.To(ctx).Start(name)
defer end()
easy to write.
But it's not possible to add additional labels that way; instead a
whole new builder needs to be constructed from scratch.
So in this CL, Start's second return value is a Builder. The simple
case is almost as short:
ctx, b := event.To(ctx).Start(name)
defer b.End()
but now it's equally easy to add more information to the end event:
ctx, b := event.To(ctx).Start(name)
defer b.With(Result.Of(err)).End()
Change-Id: Ib489a2704ac78479317eeb3f1f3de0f1b38d610c
Reviewed-on: https://go-review.googlesource.com/c/exp/+/326849
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
diff --git a/event/builder.go b/event/builder.go
index f90804f..a0567e3 100644
--- a/event/builder.go
+++ b/event/builder.go
@@ -259,26 +259,26 @@
}
// Start delivers a start event with the given name and labels.
-// Its second return value is a function that should be called to deliver the
-// matching end event.
+// Its second return value is a Builder whose End method can be
+// called to deliver the matching End event.
+// (It is also fine to ignore the Builder.)
// All events created from the returned context will have this start event
// as their parent.
-func (b Builder) Start(name string) (context.Context, func()) {
+func (b Builder) Start(name string) (context.Context, Builder) {
if b.data == nil {
- return b.ctx, func() {}
+ return b.ctx, Builder{}
}
checkValid(b.data, b.builderID)
ctx := b.ctx
- end := func() {}
+ var endBuilder Builder
if b.data.exporter.tracingEnabled() {
b.data.exporter.mu.Lock()
defer b.data.exporter.mu.Unlock()
b.data.exporter.lastEvent++
traceID := b.data.exporter.lastEvent
// create the end builder
- eb := b.Clone()
- eb.data.Event.Parent = traceID
-
+ endBuilder = b.Clone()
+ endBuilder.data.Event.Parent = traceID
b.data.Event.Labels = append(b.data.Event.Labels, Trace.Of(traceID))
b.data.exporter.prepare(&b.data.Event)
// and now deliver the start event
@@ -286,12 +286,11 @@
now := time.Now()
ctx = newContext(ctx, b.data.exporter, traceID, now)
ctx = b.data.exporter.handler.Start(ctx, &b.data.Event)
- eb.data.parentStart = now
- eb.ctx = ctx
- end = eb.End
+ endBuilder.data.parentStart = now
+ endBuilder.ctx = ctx
}
b.done()
- return ctx, end
+ return ctx, endBuilder
}
func checkValid(b *builder, wantID uint64) {
diff --git a/event/builder_test.go b/event/builder_test.go
index 4f4166c..c7d698f 100644
--- a/event/builder_test.go
+++ b/event/builder_test.go
@@ -68,12 +68,12 @@
// Verify that the context returned from the handler is also returned from Start,
// and is the context passed to End.
ctx := event.WithExporter(context.Background(), event.NewExporter(&testTraceHandler{t: t}, nil))
- ctx, end := event.To(ctx).Start("s")
+ ctx, eb := event.To(ctx).Start("s")
val := ctx.Value("x")
if val != 1 {
t.Fatal("context not returned from Start")
}
- end()
+ eb.End()
}
type testTraceHandler struct {
@@ -142,15 +142,15 @@
}
}
- t.Run("end function", func(t *testing.T) {
+ t.Run("returned builder", func(t *testing.T) {
h := &testTraceDurationHandler{}
ctx := event.WithExporter(context.Background(), event.NewExporter(h, nil))
- ctx, end := event.To(ctx).With(event.DurationMetric.Of(dur)).Start("s")
+ ctx, eb := event.To(ctx).With(event.DurationMetric.Of(dur)).Start("s")
time.Sleep(want)
- end()
+ eb.End()
check(t, h)
})
- t.Run("End method", func(t *testing.T) {
+ t.Run("separate builder", func(t *testing.T) {
h := &testTraceDurationHandler{}
ctx := event.WithExporter(context.Background(), event.NewExporter(h, nil))
ctx, _ = event.To(ctx).Start("s")
diff --git a/event/common_test.go b/event/common_test.go
index 1fdfbd5..c175dae 100644
--- a/event/common_test.go
+++ b/event/common_test.go
@@ -35,12 +35,12 @@
checkFind(t, h, "Annotate", event.Name, false, "")
h.Reset()
- _, end := event.To(ctx).Start(trace)
+ _, eb := event.To(ctx).Start(trace)
checkFind(t, h, "Start", event.Message, false, "")
checkFind(t, h, "Start", event.Name, true, trace)
h.Reset()
- end()
+ eb.End()
checkFind(t, h, "End", event.Message, false, "")
checkFind(t, h, "End", event.Name, false, "")
}
diff --git a/event/event_test.go b/event/event_test.go
index 4a01b72..d2321bb 100644
--- a/event/event_test.go
+++ b/event/event_test.go
@@ -53,8 +53,8 @@
}, {
name: "span",
events: func(ctx context.Context) {
- ctx, end := event.To(ctx).Start("span")
- end()
+ ctx, eb := event.To(ctx).Start("span")
+ eb.End()
},
expect: `
time=2020-03-05T14:27:48 trace=1 name=span
@@ -62,10 +62,10 @@
`}, {
name: "span nested",
events: func(ctx context.Context) {
- ctx, end := event.To(ctx).Start("parent")
- defer end()
- child, end2 := event.To(ctx).Start("child")
- defer end2()
+ ctx, eb := event.To(ctx).Start("parent")
+ defer eb.End()
+ child, eb2 := event.To(ctx).Start("child")
+ defer eb2.End()
event.To(child).Log("message")
},
expect: `
diff --git a/event/otel/trace_test.go b/event/otel/trace_test.go
index fe05ef0..c29f392 100644
--- a/event/otel/trace_test.go
+++ b/event/otel/trace_test.go
@@ -95,9 +95,9 @@
ctx, span = s.tracer.Start(ctx, s.name)
defer span.End()
} else {
- var end func()
- ctx, end = event.To(ctx).Start(s.name)
- defer end()
+ var eb event.Builder
+ ctx, eb = event.To(ctx).Start(s.name)
+ defer eb.End()
}
for _, c := range s.children {
c.apply(ctx)