Skip to content

Commit 2701231

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 7732541 commit 2701231

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
@@ -10,6 +10,8 @@
1010
//! export.
1111
1212
use crate::error::{ExporterError, ExporterErrorCode as ErrorCode};
13+
use crate::response::ExporterResponse;
14+
use crate::trace_exporter::TraceExporter;
1315
use crate::{catch_panic, gen_error};
1416
use libdd_common_ffi::slice::AsBytes;
1517
use libdd_common_ffi::CharSlice;
@@ -293,6 +295,51 @@ pub unsafe extern "C" fn ddog_tracer_trace_chunks_push_span(
293295
)
294296
}
295297

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

0 commit comments

Comments
 (0)