Skip to content

Bug: Potential goroutine leak in ExchangeContext.OnCancel when context is never cancelled #4162

@hklcf

Description

@hklcf

Description

In \experimental/libbox/dns.go:122-127, the \OnCancel\ method spawns a goroutine that blocks indefinitely if the associated context is never cancelled:

go func (c *ExchangeContext) OnCancel(callback Func) { go func() { <-c.context.Done() callback.Invoke() }() }

Impact

If the \ExchangeContext\ is created with a context that is never cancelled (or has no deadline), the goroutine spawned by \OnCancel\ will live forever. Each DNS query that triggers \OnCancel\ leaks one goroutine.

While the main code path via \ ask.Group.Run()\ does cancel the context, other callers of the platform transport may not provide a cancellable context.

Location

\experimental/libbox/dns.go:122-127\

Suggested Fix

Use a select with a timeout, or ensure the goroutine respects a maximum lifetime:

go func (c *ExchangeContext) OnCancel(callback Func) { go func() { select { case <-c.context.Done(): callback.Invoke() case <-time.After(30 * time.Second): // timeout to prevent goroutine leak } }() }

Alternatively, document that the context passed to \Exchange()\ must be cancellable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions