Change Span to refer to SpanStack, rather than TracingContext. (#39)
diff --git a/e2e/src/main.rs b/e2e/src/main.rs
index cccac22..8674ed2 100644
--- a/e2e/src/main.rs
+++ b/e2e/src/main.rs
@@ -112,8 +112,8 @@
.unwrap(),
)
.unwrap();
- let mut context = tracer::create_trace_context_from_propagation(ctx);
- let _span = context.create_entry_span("/pong");
+ let mut context = tracer::create_trace_context();
+ let _span = context.create_entry_span_with_propagation("/pong", &ctx);
Ok(Response::new(Body::from("hoge")))
}
diff --git a/src/context/span.rs b/src/context/span.rs
index 692b653..8fced96 100644
--- a/src/context/span.rs
+++ b/src/context/span.rs
@@ -14,12 +14,17 @@
// limitations under the License.
//
-use crate::skywalking_proto::v3::{SpanLayer, SpanObject, SpanType};
-use std::fmt::Formatter;
-
use super::{
system_time::{fetch_time, TimePeriod},
- trace_context::{TracingContext, WeakTracingContext},
+ trace_context::SpanStack,
+};
+use crate::{
+ error::LOCK_MSG,
+ skywalking_proto::v3::{SpanLayer, SpanObject, SpanType},
+};
+use std::{
+ fmt::Formatter,
+ sync::{Arc, Weak},
};
/// Span is a concept that represents trace information for a single RPC.
@@ -60,34 +65,38 @@
#[must_use = "assign a variable name to guard the span not be dropped immediately."]
pub struct Span {
index: usize,
- context: WeakTracingContext,
+ stack: Weak<SpanStack>,
}
impl std::fmt::Debug for Span {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
- let mut d = f.debug_struct("Span");
- match self.context.upgrade() {
- Some(context) => {
- let op = context.try_with_active_span_stack(|stack| {
- d.field("data", &stack.get(self.index));
- });
- if op.is_none() {
- d.field("data", &format_args!("<locked>"));
- }
- }
- None => {
- d.field("context", &format_args!("<dropped>"));
- }
- }
- d.finish()
+ let span_object: SpanObject;
+ f.debug_struct("Span")
+ .field(
+ "data",
+ match self.stack.upgrade() {
+ Some(stack) => match stack.active.try_read() {
+ Ok(spans) => match spans.get(self.index) {
+ Some(span) => {
+ span_object = span.clone();
+ &span_object
+ }
+ None => &"<hanged>",
+ },
+ Err(_) => &"<locked>",
+ },
+ None => &"<dropped>",
+ },
+ )
+ .finish()
}
}
const SKYWALKING_RUST_COMPONENT_ID: i32 = 11000;
impl Span {
- pub(crate) fn new(index: usize, context: WeakTracingContext) -> Self {
- Self { index, context }
+ pub(crate) fn new(index: usize, stack: Weak<SpanStack>) -> Self {
+ Self { index, stack }
}
#[allow(clippy::too_many_arguments)]
@@ -114,21 +123,17 @@
}
}
- fn upgrade_context(&self) -> TracingContext {
- self.context.upgrade().expect("Context has dropped")
+ fn upgrade_stack(&self) -> Arc<SpanStack> {
+ self.stack.upgrade().expect("Context has dropped")
}
- // Notice: Perhaps in the future, `RwLock` can be used instead of `Mutex`, so
- // `with_*` can be nested. (Although I can't find the meaning of such use at
- // present.)
pub fn with_span_object<T>(&self, f: impl FnOnce(&SpanObject) -> T) -> T {
- self.upgrade_context()
- .with_active_span_stack(|stack| f(&stack[self.index]))
+ self.upgrade_stack()
+ .with_active(|stack| f(&stack[self.index]))
}
pub fn with_span_object_mut<T>(&mut self, f: impl FnOnce(&mut SpanObject) -> T) -> T {
- self.upgrade_context()
- .with_active_span_stack_mut(|stack| f(&mut stack[self.index]))
+ f(&mut (self.upgrade_stack().active.try_write().expect(LOCK_MSG))[self.index])
}
pub fn span_id(&self) -> i32 {
@@ -159,9 +164,7 @@
///
/// Panic if context is dropped or this span isn't the active span.
fn drop(&mut self) {
- if self.upgrade_context().finalize_span(self.index).is_err() {
- panic!("Dropped span isn't the active span");
- }
+ self.upgrade_stack().finalize_span(self.index);
}
}
diff --git a/src/context/trace_context.rs b/src/context/trace_context.rs
index 107daea..be0a7a1 100644
--- a/src/context/trace_context.rs
+++ b/src/context/trace_context.rs
@@ -30,159 +30,157 @@
use std::{
fmt::Formatter,
mem::take,
- sync::{
- atomic::{AtomicI32, Ordering},
- Arc, Mutex, RwLock, Weak,
- },
+ sync::{Arc, RwLock},
};
-struct Inner {
- trace_id: RwLock<String>,
- trace_segment_id: String,
- service: String,
- service_instance: String,
- next_span_id: AtomicI32,
- spans: Mutex<Vec<SpanObject>>,
- active_span_stack: Mutex<Vec<SpanObject>>,
- segment_link: Option<PropagationContext>,
- primary_endpoint_name: Mutex<String>,
+#[derive(Default)]
+pub(crate) struct SpanStack {
+ pub(crate) finialized: RwLock<Vec<SpanObject>>,
+ pub(crate) active: RwLock<Vec<SpanObject>>,
+}
+
+impl SpanStack {
+ pub(crate) fn with_finialized<T>(&self, f: impl FnOnce(&Vec<SpanObject>) -> T) -> T {
+ f(&self.finialized.try_read().expect(LOCK_MSG))
+ }
+
+ pub(crate) fn with_finialized_mut<T>(&self, f: impl FnOnce(&mut Vec<SpanObject>) -> T) -> T {
+ f(&mut *self.finialized.try_write().expect(LOCK_MSG))
+ }
+
+ pub(crate) fn with_active<T>(&self, f: impl FnOnce(&Vec<SpanObject>) -> T) -> T {
+ f(&*self.active.try_read().expect(LOCK_MSG))
+ }
+
+ pub(crate) fn with_active_mut<T>(&self, f: impl FnOnce(&mut Vec<SpanObject>) -> T) -> T {
+ f(&mut *self.active.try_write().expect(LOCK_MSG))
+ }
+
+ fn pop_active(&self, index: usize) -> Option<SpanObject> {
+ self.with_active_mut(|stack| {
+ if stack.len() > index + 1 {
+ None
+ } else {
+ stack.pop()
+ }
+ })
+ }
+
+ /// Close span. We can't use closed span after finalize called.
+ pub(crate) fn finalize_span(&self, index: usize) {
+ let span = self.pop_active(index);
+ if let Some(mut span) = span {
+ span.end_time = fetch_time(TimePeriod::End);
+ self.with_finialized_mut(|spans| spans.push(span));
+ } else {
+ panic!("Finalize span isn't the active span");
+ }
+ }
}
#[must_use = "call `create_entry_span` after `TracingContext` created."]
pub struct TracingContext {
- inner: Arc<Inner>,
+ trace_id: String,
+ trace_segment_id: String,
+ service: String,
+ service_instance: String,
+ next_span_id: i32,
+ span_stack: Arc<SpanStack>,
+ primary_endpoint_name: String,
tracer: WeakTracer,
}
impl std::fmt::Debug for TracingContext {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ let span_objects: Vec<SpanObject>;
f.debug_struct("TracingContext")
- .field("trace_id", &self.inner.trace_id)
- .field("trace_segment_id", &self.inner.trace_segment_id)
- .field("service", &self.inner.service)
- .field("service_instance", &self.inner.service_instance)
- .field("next_span_id", &self.inner.next_span_id)
- .field("spans", &self.inner.spans)
+ .field("trace_id", &self.trace_id)
+ .field("trace_segment_id", &self.trace_segment_id)
+ .field("service", &self.service)
+ .field("service_instance", &self.service_instance)
+ .field("next_span_id", &self.next_span_id)
+ .field(
+ "finialized_spans",
+ match self.span_stack.finialized.try_read() {
+ Ok(spans) => {
+ span_objects = spans.clone();
+ &span_objects
+ }
+ Err(_) => &"<locked>",
+ },
+ )
.finish()
}
}
impl TracingContext {
- /// Generate a new trace context. Typically called when no context has
- /// been propagated and a new trace is to be started.
+ /// Generate a new trace context.
pub(crate) fn new(
service_name: impl ToString,
instance_name: impl ToString,
tracer: WeakTracer,
) -> Self {
TracingContext {
- inner: Arc::new(Inner {
- trace_id: RwLock::new(RandomGenerator::generate()),
- trace_segment_id: RandomGenerator::generate(),
- service: service_name.to_string(),
- service_instance: instance_name.to_string(),
- next_span_id: Default::default(),
- spans: Default::default(),
- segment_link: None,
- active_span_stack: Default::default(),
- primary_endpoint_name: Default::default(),
- }),
- tracer,
- }
- }
-
- /// Generate a new trace context using the propagated context.
- /// They should be propagated on `sw8` header in HTTP request with encoded
- /// form. You can retrieve decoded context with
- /// `skywalking::context::propagation::encoder::encode_propagation`
- pub(crate) fn from_propagation_context(
- service_name: impl ToString,
- instance_name: impl ToString,
- context: PropagationContext,
- tracer: WeakTracer,
- ) -> Self {
- TracingContext {
- inner: Arc::new(Inner {
- trace_id: RwLock::new(context.parent_trace_id.clone()),
- trace_segment_id: RandomGenerator::generate(),
- service: service_name.to_string(),
- service_instance: instance_name.to_string(),
- next_span_id: Default::default(),
- spans: Default::default(),
- segment_link: Some(context),
- active_span_stack: Default::default(),
- primary_endpoint_name: Default::default(),
- }),
+ trace_id: RandomGenerator::generate(),
+ trace_segment_id: RandomGenerator::generate(),
+ service: service_name.to_string(),
+ service_instance: instance_name.to_string(),
+ next_span_id: Default::default(),
+ span_stack: Default::default(),
+ primary_endpoint_name: Default::default(),
tracer,
}
}
#[inline]
- pub fn trace_id(&self) -> String {
- self.with_trace_id(ToString::to_string)
- }
-
- fn with_trace_id<T>(&self, f: impl FnOnce(&String) -> T) -> T {
- f(&*self.inner.trace_id.try_read().expect(LOCK_MSG))
- }
-
- fn with_trace_id_mut<T>(&mut self, f: impl FnOnce(&mut String) -> T) -> T {
- f(&mut *self.inner.trace_id.try_write().expect(LOCK_MSG))
+ pub fn trace_id(&self) -> &str {
+ &self.trace_id
}
#[inline]
pub fn trace_segment_id(&self) -> &str {
- &self.inner.trace_segment_id
+ &self.trace_segment_id
}
#[inline]
pub fn service(&self) -> &str {
- &self.inner.service
+ &self.service
}
#[inline]
pub fn service_instance(&self) -> &str {
- &self.inner.service_instance
+ &self.service_instance
}
fn next_span_id(&self) -> i32 {
- self.inner.next_span_id.load(Ordering::Relaxed)
+ self.next_span_id
}
#[inline]
- fn inc_next_span_id(&self) -> i32 {
- self.inner.next_span_id.fetch_add(1, Ordering::Relaxed)
+ fn inc_next_span_id(&mut self) -> i32 {
+ let span_id = self.next_span_id;
+ self.next_span_id += 1;
+ span_id
}
- #[cfg(feature = "mock")]
- pub fn with_spans<T>(&self, f: impl FnOnce(&Vec<SpanObject>) -> T) -> T {
- f(&*self.inner.spans.try_lock().expect(LOCK_MSG))
+ pub fn last_span(&self) -> Option<SpanObject> {
+ self.span_stack
+ .with_finialized(|spans| spans.last().cloned())
}
fn with_spans_mut<T>(&mut self, f: impl FnOnce(&mut Vec<SpanObject>) -> T) -> T {
- f(&mut *self.inner.spans.try_lock().expect(LOCK_MSG))
+ f(&mut *self.span_stack.finialized.try_write().expect(LOCK_MSG))
}
pub(crate) fn with_active_span_stack<T>(&self, f: impl FnOnce(&Vec<SpanObject>) -> T) -> T {
- f(&*self.inner.active_span_stack.try_lock().expect(LOCK_MSG))
+ self.span_stack.with_active(f)
}
pub(crate) fn with_active_span_stack_mut<T>(
&mut self,
f: impl FnOnce(&mut Vec<SpanObject>) -> T,
) -> T {
- f(&mut *self.inner.active_span_stack.try_lock().expect(LOCK_MSG))
- }
-
- pub(crate) fn try_with_active_span_stack<T>(
- &self,
- f: impl FnOnce(&Vec<SpanObject>) -> T,
- ) -> Option<T> {
- self.inner
- .active_span_stack
- .try_lock()
- .ok()
- .map(|stack| f(&*stack))
+ self.span_stack.with_active_mut(f)
}
pub(crate) fn with_active_span<T>(&self, f: impl FnOnce(&SpanObject) -> T) -> Option<T> {
@@ -196,19 +194,14 @@
self.with_active_span_stack_mut(|stack| stack.last_mut().map(f))
}
- fn with_primary_endpoint_name<T>(&self, f: impl FnOnce(&String) -> T) -> T {
- f(&*self.inner.primary_endpoint_name.try_lock().expect(LOCK_MSG))
- }
-
- fn with_primary_endpoint_name_mut<T>(&mut self, f: impl FnOnce(&mut String) -> T) -> T {
- f(&mut *self.inner.primary_endpoint_name.try_lock().expect(LOCK_MSG))
- }
-
/// Create a new entry span, which is an initiator of collection of spans.
/// This should be called by invocation of the function which is triggered
/// by external service.
+ ///
+ /// Typically called when no context has
+ /// been propagated and a new trace is to be started.
pub fn create_entry_span(&mut self, operation_name: &str) -> Span {
- let mut span = Span::new_obj(
+ let span = Span::new_obj(
self.inc_next_span_id(),
self.peek_active_span_id().unwrap_or(-1),
operation_name.to_string(),
@@ -218,21 +211,36 @@
false,
);
- if let Some(segment_link) = &self.inner.segment_link {
+ let index = self.push_active_span(span);
+ Span::new(index, Arc::downgrade(&self.span_stack))
+ }
+
+ /// Create a new entry span, which is an initiator of collection of spans.
+ /// This should be called by invocation of the function which is triggered
+ /// by external service.
+ ///
+ /// They should be propagated on `sw8` header in HTTP request with encoded
+ /// form. You can retrieve decoded context with
+ /// `skywalking::context::propagation::encoder::encode_propagation`
+ pub fn create_entry_span_with_propagation(
+ &mut self,
+ operation_name: &str,
+ propagation: &PropagationContext,
+ ) -> Span {
+ let mut span = self.create_entry_span(operation_name);
+ span.with_span_object_mut(|span| {
span.refs.push(SegmentReference {
ref_type: RefType::CrossProcess as i32,
- trace_id: self.trace_id(),
- parent_trace_segment_id: segment_link.parent_trace_segment_id.clone(),
- parent_span_id: segment_link.parent_span_id,
- parent_service: segment_link.parent_service.clone(),
- parent_service_instance: segment_link.parent_service_instance.clone(),
- parent_endpoint: segment_link.destination_endpoint.clone(),
- network_address_used_at_peer: segment_link.destination_address.clone(),
+ trace_id: self.trace_id().to_owned(),
+ parent_trace_segment_id: propagation.parent_trace_segment_id.clone(),
+ parent_span_id: propagation.parent_span_id,
+ parent_service: propagation.parent_service.clone(),
+ parent_service_instance: propagation.parent_service_instance.clone(),
+ parent_endpoint: propagation.destination_endpoint.clone(),
+ network_address_used_at_peer: propagation.destination_address.clone(),
});
- }
-
- let index = self.push_active_span(span);
- Span::new(index, self.downgrade())
+ });
+ span
}
/// Create a new exit span, which will be created when tracing context will
@@ -258,7 +266,7 @@
);
let index = self.push_active_span(span);
- Span::new(index, self.downgrade())
+ Span::new(index, Arc::downgrade(&self.span_stack))
}
/// Create a new local span.
@@ -282,23 +290,23 @@
);
let index = self.push_active_span(span);
- Span::new(index, self.downgrade())
+ Span::new(index, Arc::downgrade(&self.span_stack))
}
/// Capture a snapshot for cross-thread propagation.
pub fn capture(&self) -> ContextSnapshot {
ContextSnapshot {
- trace_id: self.trace_id(),
+ trace_id: self.trace_id().to_owned(),
trace_segment_id: self.trace_segment_id().to_owned(),
span_id: self.peek_active_span_id().unwrap_or(-1),
- parent_endpoint: self.with_primary_endpoint_name(Clone::clone),
+ parent_endpoint: self.primary_endpoint_name.clone(),
}
}
/// Build the reference between this segment and a cross-thread segment.
pub fn continued(&mut self, snapshot: ContextSnapshot) {
if snapshot.is_valid() {
- self.with_trace_id_mut(|trace_id| *trace_id = snapshot.trace_id.clone());
+ self.trace_id = snapshot.trace_id.clone();
let tracer = self.upgrade_tracer();
@@ -319,24 +327,12 @@
}
}
- /// Close span. We can't use closed span after finalize called.
- pub(crate) fn finalize_span(&mut self, index: usize) -> Result<(), ()> {
- let span = self.pop_active_span(index);
- if let Some(mut span) = span {
- span.end_time = fetch_time(TimePeriod::End);
- self.with_spans_mut(|spans| spans.push(span));
- Ok(())
- } else {
- Err(())
- }
- }
-
/// It converts tracing context into segment object.
/// This conversion should be done before sending segments into OAP.
///
/// Notice: The spans will taked, so this method shouldn't be called twice.
pub(crate) fn convert_segment_object(&mut self) -> SegmentObject {
- let trace_id = self.trace_id();
+ let trace_id = self.trace_id().to_owned();
let trace_segment_id = self.trace_segment_id().to_owned();
let service = self.service().to_owned();
let service_instance = self.service_instance().to_owned();
@@ -357,30 +353,13 @@
}
fn push_active_span(&mut self, span: SpanObject) -> usize {
- self.with_primary_endpoint_name_mut(|endpoint| *endpoint = span.operation_name.clone());
+ self.primary_endpoint_name = span.operation_name.clone();
self.with_active_span_stack_mut(|stack| {
stack.push(span);
stack.len() - 1
})
}
- fn pop_active_span(&mut self, index: usize) -> Option<SpanObject> {
- self.with_active_span_stack_mut(|stack| {
- if stack.len() > index + 1 {
- None
- } else {
- stack.pop()
- }
- })
- }
-
- fn downgrade(&self) -> WeakTracingContext {
- WeakTracingContext {
- inner: Arc::downgrade(&self.inner),
- tracer: self.tracer.clone(),
- }
- }
-
fn upgrade_tracer(&self) -> Tracer {
self.tracer.upgrade().expect("Tracer has dropped")
}
@@ -393,24 +372,7 @@
///
/// Panic if tracer is dropped.
fn drop(&mut self) {
- if Arc::strong_count(&self.inner) <= 1 {
- self.upgrade_tracer().finalize_context(self)
- }
- }
-}
-
-#[derive(Clone)]
-pub(crate) struct WeakTracingContext {
- inner: Weak<Inner>,
- tracer: WeakTracer,
-}
-
-impl WeakTracingContext {
- pub(crate) fn upgrade(&self) -> Option<TracingContext> {
- self.inner.upgrade().map(|inner| TracingContext {
- inner,
- tracer: self.tracer.clone(),
- })
+ self.upgrade_tracer().finalize_context(self)
}
}
diff --git a/src/context/tracer.rs b/src/context/tracer.rs
index f528b1f..bb161b8 100644
--- a/src/context/tracer.rs
+++ b/src/context/tracer.rs
@@ -14,7 +14,6 @@
// limitations under the License.
//
-use super::propagation::context::PropagationContext;
use crate::{
context::trace_context::TracingContext,
reporter::{DynReporter, Reporter},
@@ -59,11 +58,6 @@
global_tracer().create_trace_context()
}
-/// Create trace conetxt from propagation by global tracer.
-pub fn create_trace_context_from_propagation(context: PropagationContext) -> TracingContext {
- global_tracer().create_trace_context_from_propagation(context)
-}
-
/// Start to reporting by global tracer, quit when shutdown_signal received.
///
/// Accept a `shutdown_signal` argument as a graceful shutdown signal.
@@ -129,7 +123,7 @@
instance_name: String,
segment_sender: Box<dyn SegmentSender>,
segment_receiver: Box<dyn SegmentReceiver>,
- reporter: Box<Mutex<DynReporter>>,
+ reporter: Mutex<Box<DynReporter>>,
is_reporting: AtomicBool,
is_closed: AtomicBool,
}
@@ -169,7 +163,7 @@
instance_name: instance_name.to_string(),
segment_sender: Box::new(channel.0),
segment_receiver: Box::new(channel.1),
- reporter: Box::new(Mutex::new(reporter)),
+ reporter: Mutex::new(Box::new(reporter)),
is_reporting: Default::default(),
is_closed: Default::default(),
}),
@@ -184,6 +178,15 @@
&self.inner.instance_name
}
+ /// Set the reporter, only valid if [`Tracer::reporting`] not started.
+ pub fn set_reporter(&self, reporter: impl Reporter + Send + Sync + 'static) {
+ if !self.inner.is_reporting.load(Ordering::Relaxed) {
+ if let Ok(mut lock) = self.inner.reporter.try_lock() {
+ *lock = Box::new(reporter);
+ }
+ }
+ }
+
/// Create trace conetxt.
pub fn create_trace_context(&self) -> TracingContext {
TracingContext::new(
@@ -193,19 +196,6 @@
)
}
- /// Create trace conetxt from propagation.
- pub fn create_trace_context_from_propagation(
- &self,
- context: PropagationContext,
- ) -> TracingContext {
- TracingContext::from_propagation_context(
- &self.inner.service_name,
- &self.inner.instance_name,
- context,
- self.downgrade(),
- )
- }
-
/// Finalize the trace context.
pub(crate) fn finalize_context(&self, context: &mut TracingContext) {
if self.inner.is_closed.load(Ordering::Relaxed) {
@@ -294,7 +284,7 @@
}
async fn report_segment_object(
- reporter: &Mutex<DynReporter>,
+ reporter: &Mutex<Box<DynReporter>>,
segments: LinkedList<SegmentObject>,
) {
if let Err(err) = reporter.lock().await.collect(segments).await {
diff --git a/tests/trace_context.rs b/tests/trace_context.rs
index d3c9238..3a15d30 100644
--- a/tests/trace_context.rs
+++ b/tests/trace_context.rs
@@ -115,9 +115,7 @@
logs: Vec::<Log>::new(),
skip_analysis: false,
};
- context.with_spans(|spans| {
- assert_eq!(spans.last(), Some(&span3_expected));
- });
+ assert_eq!(context.last_span(), Some(span3_expected));
}
{
@@ -143,9 +141,7 @@
logs: Vec::<Log>::new(),
skip_analysis: false,
};
- context.with_spans(|spans| {
- assert_eq!(spans.last(), Some(&span5_expected));
- });
+ assert_eq!(context.last_span(), Some(span5_expected));
}
}
@@ -167,9 +163,7 @@
logs: expected_log,
skip_analysis: false,
};
- context.with_spans(|spans| {
- assert_eq!(spans.last(), Some(&span1_expected));
- });
+ assert_eq!(context.last_span(), Some(span1_expected));
}
tracer
@@ -209,7 +203,8 @@
MockReporter::with(
|reporter| {
let tracer = Tracer::new("service2", "instance2", reporter);
- let _context = tracer.create_trace_context_from_propagation(prop);
+ let mut context = tracer.create_trace_context();
+ let _span = context.create_entry_span_with_propagation("operation_name", &prop);
tracer
},
|segment| {
@@ -239,30 +234,29 @@
let dec_prop = decode_propagation(&enc_prop).unwrap();
let tracer = Tracer::new("service2", "instance2", LogReporter::new());
- let mut context2 = tracer.create_trace_context_from_propagation(dec_prop);
+ let mut context2 = tracer.create_trace_context();
- let span3 = context2.create_entry_span("op2");
+ let span3 = context2.create_entry_span_with_propagation("op2", &dec_prop);
drop(span3);
- context2.with_spans(|spans| {
- let span3 = spans.last().unwrap();
- assert_eq!(span3.span_id, 0);
- assert_eq!(span3.parent_span_id, -1);
- assert_eq!(span3.refs.len(), 1);
+ let span3 = context2.last_span().unwrap();
- let expected_ref = SegmentReference {
- ref_type: RefType::CrossProcess as i32,
- trace_id: context2.trace_id().to_owned(),
- parent_trace_segment_id: context1.trace_segment_id().to_owned(),
- parent_span_id: 1,
- parent_service: context1.service().to_owned(),
- parent_service_instance: context1.service_instance().to_owned(),
- parent_endpoint: "endpoint".to_string(),
- network_address_used_at_peer: "address".to_string(),
- };
+ assert_eq!(span3.span_id, 0);
+ assert_eq!(span3.parent_span_id, -1);
+ assert_eq!(span3.refs.len(), 1);
- check_serialize_equivalent(&expected_ref, &span3.refs[0]);
- });
+ let expected_ref = SegmentReference {
+ ref_type: RefType::CrossProcess as i32,
+ trace_id: context2.trace_id().to_owned(),
+ parent_trace_segment_id: context1.trace_segment_id().to_owned(),
+ parent_span_id: 1,
+ parent_service: context1.service().to_owned(),
+ parent_service_instance: context1.service_instance().to_owned(),
+ parent_endpoint: "endpoint".to_string(),
+ network_address_used_at_peer: "address".to_string(),
+ };
+
+ check_serialize_equivalent(&expected_ref, &span3.refs[0]);
}
}
}