Skip to content

Guarantee ForceFlush of BatchSpanProcessor will export all ended spans #2080

Closed
@garrettwegan

Description

Problem Statement

Currently calling ForceFlush on a BatchSpanProcessor will export all spans which have been ended AND consumed into the BSP's batch. However, spans which have been ended before a call to ForceFlush are not guaranteed to be consumed into the batch and therefore may or may not be exported by ForceFlush as desired.

Proposed Solution

I would like ForceFlush to ensure any ended spans are indeed exported following a call to ForceFlush.

I have attempted to modify ForceFlush myself to process the queue before exporting but have achieved only mixed results.

Prior Art

Using runtime.Gosched() either within ForceFlush or in user code before calling ForceFlush to yield execution and allow consumption to occur naturally is very likely to populate the batch with any ended spans, but is not guaranteed to do so.

Additional Context

A simple test case which would pass after such a change is as follows:

// Sometimes passes
func TestBSPForce(t *testing.T) {
	ctx := context.Background()

	exp := tracetest.NewInMemoryExporter()

	tp := sdktrace.NewTracerProvider(
		sdktrace.WithBatcher(exp),
	)

	tracer := tp.Tracer("tracer")

	_, span := tracer.Start(ctx, "span")
	span.End()
	
	// runtime.Gosched() - with this uncommented I have yet to see this test fail but would like a stronger guarantee
	err := tp.ForceFlush(ctx)
	assert.NoError(t, err)

	// Expect well defined behavior due to calling ForceFlush
	assert.Len(t, exp.GetSpans(), 1)
}

Intuitively I would already expect this test case to pass, however, current behavior of the BatchSpanProcessor causes the result of this test case to be inconsistent.

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions