Skip to content

Commit 2b39efc

Browse files
committed
Add ddog_trace_exporter_send_trace_chunks FFI function
Wire `TracerTraceChunks` to the existing `TraceExporter::send_trace_chunks` method through a new C-callable function. The chunks are consumed on call and the agent response is optionally written to an out-parameter. This completes the span-building FFI surface: callers can now construct spans via `ddog_tracer_span_*`, group them via `ddog_tracer_trace_chunks_*`, and send them via `ddog_trace_exporter_send_trace_chunks` — all without serializing to msgpack on the caller side. The `TraceExporter` type alias in `trace_exporter.rs` is widened to `pub(crate)` to allow cross-module access.
1 parent c45b69d commit 2b39efc

2 files changed

Lines changed: 48 additions & 1 deletion

File tree

libdd-data-pipeline-ffi/src/trace_exporter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use libdd_data_pipeline::trace_exporter::{
1414
TraceExporterInputFormat, TraceExporterOutputFormat,
1515
};
1616

17-
type TraceExporter = GenericTraceExporter<NativeCapabilities>;
17+
pub(crate) type TraceExporter = GenericTraceExporter<NativeCapabilities>;
1818

1919
use libdd_shared_runtime::SharedRuntime;
2020
use std::{ptr::NonNull, sync::Arc, time::Duration};

libdd-data-pipeline-ffi/src/tracer.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
//! into trace chunks ready for export.
1212
1313
use crate::error::{ExporterError, ExporterErrorCode as ErrorCode};
14+
use crate::response::ExporterResponse;
15+
use crate::trace_exporter::TraceExporter;
1416
use crate::{catch_panic, gen_error};
1517
use libdd_common_ffi::slice::AsBytes;
1618
use libdd_common_ffi::CharSlice;
@@ -294,6 +296,51 @@ pub unsafe extern "C" fn ddog_tracer_trace_chunks_push_span(
294296
)
295297
}
296298

299+
// ---------------------------------------------------------------------------
300+
// Send trace chunks
301+
// ---------------------------------------------------------------------------
302+
303+
/// Send trace chunks through a [`TraceExporter`], consuming the chunks.
304+
///
305+
/// This calls `TraceExporter::send_trace_chunks` which processes stats,
306+
/// serializes in the configured output format, and sends to the agent
307+
/// with retry logic.
308+
///
309+
/// On success, if `response_out` is non-null, a heap-allocated
310+
/// [`ExporterResponse`] is written there. The caller owns it and must
311+
/// free it with `ddog_trace_exporter_response_free`.
312+
///
313+
/// # Safety
314+
///
315+
/// * `exporter` must be a valid `TraceExporter` pointer.
316+
/// * `chunks` is consumed and must not be used after this call.
317+
/// * If `response_out` is non-null it must point to valid writable
318+
/// memory for a `Box<ExporterResponse>`.
319+
#[no_mangle]
320+
pub unsafe extern "C" fn ddog_trace_exporter_send_trace_chunks(
321+
exporter: Option<&TraceExporter>,
322+
chunks: Box<TracerTraceChunks>,
323+
response_out: Option<NonNull<Box<ExporterResponse>>>,
324+
) -> Option<Box<ExporterError>> {
325+
let exporter = match exporter {
326+
Some(e) => e,
327+
None => return gen_error!(ErrorCode::InvalidArgument),
328+
};
329+
330+
catch_panic!(
331+
match exporter.send_trace_chunks(chunks.0) {
332+
Ok(resp) => {
333+
if let Some(out) = response_out {
334+
out.as_ptr().write(Box::new(ExporterResponse::from(resp)));
335+
}
336+
None
337+
}
338+
Err(e) => Some(Box::new(ExporterError::from(e))),
339+
},
340+
gen_error!(ErrorCode::Panic)
341+
)
342+
}
343+
297344
#[cfg(test)]
298345
mod tests {
299346
use super::*;

0 commit comments

Comments
 (0)