Skip to content

feat: add async-await APIs for exporters#46

Open
gmoraleda wants to merge 6 commits intoopen-telemetry:mainfrom
gmoraleda:feat/async-exporter-apis
Open

feat: add async-await APIs for exporters#46
gmoraleda wants to merge 6 commits intoopen-telemetry:mainfrom
gmoraleda:feat/async-exporter-apis

Conversation

@gmoraleda
Copy link
Copy Markdown
Contributor

@gmoraleda gmoraleda commented Mar 12, 2026

Summary

Adds async overloads to the three exporter protocols (SpanExporter, LogRecordExporter, MetricExporter) so callers can use await exporter.export(...) in async contexts.

  • Async overloads share the same method names as their sync counterparts — Swift disambiguates via the async keyword
  • Default implementations use assertionFailure to surface unimplemented async methods during development
  • Convenience overloads without explicitTimeout delegate to the primary async methods
  • MultiSpanExporter runs child exporters concurrently via TaskGroup; MultiLogRecordExporter calls children sequentially
  • ExportResult and SpanExporterResultCode are now Sendable
  • MultiLogRecordExporter gains @unchecked Sendable conformance (immutable stored property)

Test plan

  • New AsyncSpanExporterTests, AsyncLogRecordExporterTests, AsyncMetricExporterTests covering:
    • Async-capable exporter dispatch
    • Multi-exporter concurrent/sequential forwarding
    • Failure propagation and result merging
    • Sync method compatibility
  • All 548 existing tests unaffected

@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla bot commented Mar 12, 2026

CLA Signed

The committers listed above are authorized under a signed CLA.

@gmoraleda gmoraleda force-pushed the feat/async-exporter-apis branch 4 times, most recently from b0006b3 to 9b09eb6 Compare March 12, 2026 19:31
@gmoraleda gmoraleda force-pushed the feat/async-exporter-apis branch from 90ddf33 to 495deb8 Compare March 25, 2026 13:07
@nachoBonafonte
Copy link
Copy Markdown
Member

We are not sure this is the preferred approach for adding asynchronous support to export methods, we would prefer to have async variants of the existing methods and protocols not new classes. Default no-op implementations should be provided in the extension of the protocol until everything is migrated.

@gmoraleda
Copy link
Copy Markdown
Contributor Author

Thanks for the feedback!
I agree. I'll rework the approach to add async method variants directly to the existing *Exporter protocols as extension methods with default implementations.

Will push the updated PR shortly.

@gmoraleda
Copy link
Copy Markdown
Contributor Author

hmm, thinking about it: with no-op as default implementation, an exporter calling the async method would silently succeed without exporting anything.

Should we bridge to the existing methods instead? @nachoBonafonte

gmoraleda added a commit to gmoraleda/opentelemetry-swift-core that referenced this pull request Apr 9, 2026
Replace separate AsyncSpanExporter, AsyncLogRecordExporter, and
AsyncMetricExporter protocols with async extension methods on the
existing SpanExporter, LogRecordExporter, and MetricExporter protocols.

Default implementations bridge to sync methods. Multi-exporters use
withTaskGroup for SpanExporter (Sendable) and sequential dispatch for
LogRecordExporter (not Sendable). No runtime type-checking needed.

Addresses review feedback on open-telemetry#46.
@gmoraleda gmoraleda force-pushed the feat/async-exporter-apis branch from 495deb8 to 2c000d3 Compare April 9, 2026 19:45
@nachoBonafonte
Copy link
Copy Markdown
Member

Another option is adding something like assert(false) which would make it fail in Debug while development to be sure that misuse is detected during development

@nachoBonafonte
Copy link
Copy Markdown
Member

Also regarding the methods, they don't need a new name, the compiler should select the appropriate one just with the async in the definition, and use the async method when called with await

Add new async protocols (AsyncSpanExporter, AsyncLogRecordExporter,
AsyncMetricExporter) that refine the existing sync exporter protocols,
enabling truly non-blocking exports for network-based exporters.

Default implementations bridge to sync methods via base protocol cast,
so existing exporters work unchanged. MultiSpanExporter and
MultiLogRecordExporter gain concurrent export via withTaskGroup.

Multi-exporters partition children into async (Sendable, concurrent via
TaskGroup) and sync (sequential, never cross concurrency boundaries),
avoiding @unchecked Sendable wrappers.

Also adds Sendable conformance to ExportResult and SpanExporterResultCode,
marks MultiLogRecordExporter as @unchecked Sendable with immutable storage.

Closes open-telemetry#34
…tioning logic

Add Sendable conformance to AsyncSpanExporter for consistency with
AsyncLogRecordExporter and AsyncMetricExporter. Extract repeated
async/sync exporter partitioning in MultiLogRecordExporter into a
private helper method.
Replace separate AsyncSpanExporter, AsyncLogRecordExporter, and
AsyncMetricExporter protocols with async extension methods on the
existing SpanExporter, LogRecordExporter, and MetricExporter protocols.

Default implementations bridge to sync methods. Multi-exporters use
withTaskGroup for SpanExporter (Sendable) and sequential dispatch for
LogRecordExporter (not Sendable). No runtime type-checking needed.

Addresses review feedback on open-telemetry#46.
…rtionFailure defaults

Promote async methods from extension-only to protocol requirements on
SpanExporter, LogRecordExporter, and MetricExporter. Default
implementations use assertionFailure() to catch misuse during
development. This ensures proper dynamic dispatch through protocol-typed
references and convenience overload chains—extension-only methods use
static dispatch, which silently resolves to the wrong implementation.

Existing conformers compile without changes since the defaults satisfy
the new requirements.
Swift disambiguates sync/async overloads by the `async` keyword,
so the methods can share names with their sync counterparts.
@gmoraleda gmoraleda force-pushed the feat/async-exporter-apis branch from 054ec3c to 8f39c19 Compare April 17, 2026 09:15
@gmoraleda
Copy link
Copy Markdown
Contributor Author

/rerun

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants