1use crate::{CallContext, DbScopeDiagnosticIdentity};
4use serde::{Serialize, Serializer, ser::SerializeStruct};
5use std::sync::{
6 Arc, OnceLock,
7 atomic::{AtomicU64, Ordering},
8};
9
10static NEXT_ROOT: AtomicU64 = AtomicU64::new(1);
11
12#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
14#[serde(tag = "state", content = "value", rename_all = "snake_case")]
15pub enum ContextFact<T> {
16 Present(T),
17 NotApplicable,
18 NotEstablished,
19 Unavailable,
20}
21
22#[derive(Clone, Copy, Eq, PartialEq)]
24pub struct ContextIdentity {
25 bytes: [u8; 256],
26 len: u16,
27}
28impl ContextIdentity {
29 pub fn checked(value: &str) -> Result<Self, ContextConflict> {
30 if value.is_empty() || value.len() > 256 || value.chars().any(char::is_control) {
31 return Err(ContextConflict::InvalidIdentity);
32 }
33 let mut out = Self {
34 bytes: [0; 256],
35 len: value.len() as u16,
36 };
37 out.bytes[..value.len()].copy_from_slice(value.as_bytes());
38 Ok(out)
39 }
40 fn as_str(&self) -> &str {
41 std::str::from_utf8(&self.bytes[..usize::from(self.len)]).expect("validated UTF-8")
42 }
43}
44impl Serialize for ContextIdentity {
45 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
46 s.serialize_str(self.as_str())
47 }
48}
49
50#[derive(Clone, Copy, Eq, PartialEq, Serialize)]
52#[serde(transparent)]
53pub struct ContextLabel(ContextIdentity);
54impl ContextLabel {
55 pub fn checked(value: &str) -> Result<Self, ContextConflict> {
56 let value = ContextIdentity::checked(value)?;
57 if value.as_str().contains("://")
58 || !value
59 .as_str()
60 .chars()
61 .all(|c| c.is_alphanumeric() || "_.:/{}*-".contains(c))
62 {
63 return Err(ContextConflict::UnsafeMetadata);
64 }
65 Ok(Self(value))
66 }
67}
68
69#[derive(Clone, Copy, Debug, Eq, PartialEq)]
70pub enum ContextConflict {
71 InvalidIdentity,
72 UnsafeMetadata,
73 IdentityGroup,
74 ForeignRoot,
75 ChildRelation,
76 CounterExhausted,
77}
78
79#[derive(Eq, PartialEq)]
82pub struct RequestIdentityGroup {
83 application: ContextLabel,
84 module: ContextLabel,
85 service: ContextLabel,
86 operation: ContextLabel,
87 trace: ContextIdentity,
88 rpc: ContextFact<ContextIdentity>,
89 span: u64,
90 request: ContextIdentity,
91 route: ContextLabel,
92 attempt: u32,
93 zone: ContextFact<ContextLabel>,
94}
95impl RequestIdentityGroup {
96 pub fn from_validated(
97 call: &CallContext,
98 request: &str,
99 route: &str,
100 attempt: u32,
101 zone: ContextFact<ContextLabel>,
102 ) -> Result<Self, ContextConflict> {
103 if attempt == 0 {
104 return Err(ContextConflict::InvalidIdentity);
105 }
106 Ok(Self {
107 application: ContextLabel::checked(call.application().as_str())?,
108 module: ContextLabel::checked(call.module().as_str())?,
109 service: ContextLabel::checked(call.service().as_str())?,
110 operation: ContextLabel::checked(call.operation().as_str())?,
111 trace: ContextIdentity::checked(call.trace_correlation_id().as_str())?,
112 rpc: match call.rpc_correlation_id() {
113 Some(id) => ContextFact::Present(ContextIdentity::checked(id.as_str())?),
114 None => ContextFact::Unavailable,
115 },
116 span: call.span_id().as_u64(),
117 request: ContextIdentity::checked(request)?,
118 route: ContextLabel::checked(route)?,
119 attempt,
120 zone,
121 })
122 }
123}
124
125struct RequestRoot {
126 local: u64,
127 application: ContextLabel,
128 initial: ContextFact<()>,
129 identity: OnceLock<RequestIdentityGroup>,
130}
131impl Drop for RequestRoot {
132 fn drop(&mut self) {
133 observe(self.local, "root_drop");
134 }
135}
136
137pub struct RequestRootPublisher {
144 root: Arc<RequestRoot>,
145}
146
147pub struct RequestRootRef {
149 root: Arc<RequestRoot>,
150}
151impl Clone for RequestRootRef {
152 fn clone(&self) -> Self {
153 observe(self.root.local, "root_share");
154 Self {
155 root: Arc::clone(&self.root),
156 }
157 }
158}
159impl Drop for RequestRootRef {
160 fn drop(&mut self) {
161 observe(self.root.local, "root_release");
162 }
163}
164
165impl RequestRootPublisher {
166 pub fn create(
169 application: ContextLabel,
170 initial: ContextFact<()>,
171 ) -> Result<Self, ContextConflict> {
172 if matches!(initial, ContextFact::Present(())) {
173 return Err(ContextConflict::InvalidIdentity);
174 }
175 let local = NEXT_ROOT
176 .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |n| n.checked_add(1))
177 .map_err(|_| ContextConflict::CounterExhausted)?;
178 let root = Arc::new(RequestRoot {
179 local,
180 application,
181 initial,
182 identity: OnceLock::new(),
183 });
184 observe(local, "root_create");
185 Ok(Self { root })
186 }
187 pub fn reference(&self) -> RequestRootRef {
188 observe(self.root.local, "root_share");
189 RequestRootRef {
190 root: Arc::clone(&self.root),
191 }
192 }
193 #[allow(clippy::result_large_err)] pub fn publish(
195 &mut self,
196 group: RequestIdentityGroup,
197 ) -> Result<(), (ContextConflict, RequestIdentityGroup)> {
198 if group.application != self.root.application {
199 return Err((ContextConflict::IdentityGroup, group));
200 }
201 if let Some(old) = self.root.identity.get() {
202 return if old == &group {
203 Ok(())
204 } else {
205 Err((ContextConflict::IdentityGroup, group))
206 };
207 }
208 self.root
209 .identity
210 .set(group)
211 .map_err(|group| (ContextConflict::IdentityGroup, group))
212 }
213}
214
215#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
217#[serde(rename_all = "snake_case")]
218pub enum RequestViewPhase {
219 SocketAccepted,
220 Reading,
221 Admitted,
222 Dispatch,
223 Handler,
224 Database,
225 Outbound,
226 Response,
227 Finalizing,
228 Finished,
229}
230
231#[derive(Clone, Copy, Eq, PartialEq, Serialize)]
233pub struct RegisteredContextOperation(&'static str);
234impl RegisteredContextOperation {
235 pub fn checked(value: &'static str) -> Result<Self, ContextConflict> {
236 ContextLabel::checked(value)?;
237 Ok(Self(value))
238 }
239}
240
241#[derive(Clone, Copy)]
242pub struct RequestLocalFacts {
243 task: ContextFact<u64>,
244 scope: ContextFact<DbScopeDiagnosticIdentity>,
245 db_operation: ContextFact<RegisteredContextOperation>,
246 phase: RequestViewPhase,
247}
248impl RequestLocalFacts {
249 pub fn new(phase: RequestViewPhase) -> Self {
250 Self {
251 task: ContextFact::NotEstablished,
252 scope: ContextFact::NotEstablished,
253 db_operation: ContextFact::NotApplicable,
254 phase,
255 }
256 }
257 pub fn with_task(mut self, task: ContextFact<u64>) -> Self {
259 self.task = task;
260 self
261 }
262 pub fn without_scope(mut self, state: ContextFact<()>) -> Self {
263 self.scope = absent(state);
264 self
265 }
266 pub fn with_db_operation(mut self, operation: RegisteredContextOperation) -> Self {
267 self.db_operation = ContextFact::Present(operation);
268 self
269 }
270}
271
272struct ChildCall {
275 #[cfg(test)]
276 observation: LocalObservation,
277 application: ContextLabel,
278 module: ContextLabel,
279 service: ContextLabel,
280 operation: ContextLabel,
281 rpc: ContextIdentity,
282 span: u64,
283 route: ContextLabel,
284 attempt: u32,
285}
286struct LocalView {
287 #[cfg(test)]
288 observation: LocalObservation,
289 root: Arc<RequestRoot>,
290 published: bool,
291 facts: RequestLocalFacts,
292 child: Option<Arc<ChildCall>>,
293}
294impl Drop for LocalView {
295 fn drop(&mut self) {
296 observe(self.root.local, "view_drop");
297 #[cfg(test)]
298 self.observation.record("destroy");
299 }
300}
301impl Drop for ChildCall {
302 fn drop(&mut self) {
303 #[cfg(test)]
304 self.observation.record("destroy");
305 }
306}
307
308pub struct RequestExecutionView {
316 inner: Arc<LocalView>,
317}
318
319#[derive(Clone, Copy, Serialize)]
322pub struct RequestContextSnapshot {
323 schema_version: u8,
324 local_request: u64,
325 publication: u8,
326 application: ContextFact<ContextLabel>,
327 call_application: ContextFact<ContextLabel>,
328 module: ContextFact<ContextLabel>,
329 service: ContextFact<ContextLabel>,
330 operation: ContextFact<ContextLabel>,
331 trace_id: ContextFact<ContextIdentity>,
332 request: ContextFact<ContextIdentity>,
333 span_id: ContextFact<SpanProjection>,
334 route: ContextFact<ContextLabel>,
335 attempt: ContextFact<u32>,
336 rpc_id: ContextFact<ContextIdentity>,
337 zone: ContextFact<ContextLabel>,
338 db_operation: ContextFact<RegisteredContextOperation>,
339 scope: ContextFact<DbScopeDiagnosticIdentity>,
340 task: ContextFact<u64>,
341 lifecycle: ContextFact<RequestViewPhase>,
342 target: ContextFact<ContextLabel>,
343}
344impl RequestContextSnapshot {
345 #[doc(hidden)]
346 pub fn local_request_id(&self) -> u64 { self.local_request }
347}
348pub struct OutboundSourceContext<'a> {
351 view: &'a RequestExecutionView,
352 business_unit: &'a str,
353}
354impl Clone for RequestExecutionView {
355 fn clone(&self) -> Self {
356 #[cfg(test)]
357 self.inner.observation.record("share");
358 Self {
359 inner: Arc::clone(&self.inner),
360 }
361 }
362}
363impl Drop for RequestExecutionView {
364 fn drop(&mut self) {
365 #[cfg(test)]
366 self.inner.observation.record("release");
367 }
368}
369impl RequestRootRef {
370 pub fn view(&self, facts: RequestLocalFacts) -> RequestExecutionView {
371 RequestExecutionView::allocate(
372 Arc::clone(&self.root),
373 self.root.identity.get().is_some(),
374 facts,
375 None,
376 )
377 }
378 pub fn same_request(&self, view: &RequestExecutionView) -> bool {
379 Arc::ptr_eq(&self.root, &view.inner.root)
380 }
381}
382impl RequestExecutionView {
383 pub fn diagnostic_snapshot(&self) -> RequestContextSnapshot {
384 let identity = self.identity();
385 let child = self.inner.child.as_deref();
386 let initial = self.inner.root.initial;
387 macro_rules! root {
388 ($field:ident) => { identity.map_or_else(|| absent(initial), |g| ContextFact::Present(g.$field)) };
389 }
390 macro_rules! call {
391 ($field:ident) => { child.map(|c| c.$field).or_else(|| identity.map(|g| g.$field))
392 .map_or_else(|| absent(initial), ContextFact::Present) };
393 }
394 RequestContextSnapshot {
395 schema_version: 2,
396 local_request: self.inner.root.local,
397 publication: u8::from(self.inner.published),
398 application: ContextFact::Present(self.inner.root.application),
399 call_application: ContextFact::Present(child.map_or(self.inner.root.application, |c| c.application)),
400 module: call!(module), service: call!(service), operation: call!(operation),
401 trace_id: root!(trace), request: root!(request),
402 span_id: child.map(|c| c.span).or_else(|| identity.map(|g| g.span))
403 .map_or_else(|| absent(initial), |span| ContextFact::Present(SpanProjection(span))),
404 route: call!(route), attempt: call!(attempt),
405 rpc_id: child.map(|c| ContextFact::Present(c.rpc)).or_else(|| identity.map(|g| g.rpc))
406 .unwrap_or_else(|| absent(initial)),
407 zone: identity.map_or_else(|| absent(initial), |g| g.zone),
408 db_operation: self.inner.facts.db_operation, scope: self.inner.facts.scope,
409 task: self.inner.facts.task, lifecycle: ContextFact::Present(self.inner.facts.phase),
410 target: child.map_or(ContextFact::NotApplicable, |c| ContextFact::Present(c.route)),
411 }
412 }
413 pub fn outbound_source_context<'a>(&'a self, business_unit: &'a str) -> OutboundSourceContext<'a> {
414 OutboundSourceContext { view: self, business_unit }
415 }
416 fn allocate(
417 root: Arc<RequestRoot>,
418 published: bool,
419 facts: RequestLocalFacts,
420 child: Option<Arc<ChildCall>>,
421 ) -> Self {
422 observe(root.local, "view_create");
423 Self {
424 inner: Arc::new(LocalView {
425 #[cfg(test)]
426 observation: LocalObservation::create(root.local, "view"),
427 root,
428 published,
429 facts,
430 child,
431 }),
432 }
433 }
434 fn local(&self, facts: RequestLocalFacts) -> Self {
436 Self::allocate(
437 Arc::clone(&self.inner.root),
438 self.inner.published,
439 facts,
440 self.inner.child.clone(),
441 )
442 }
443 pub fn with_phase(&self, phase: RequestViewPhase) -> Self {
444 let mut facts = self.inner.facts;
445 facts.phase = phase;
446 self.local(facts)
447 }
448 pub fn with_db_operation(&self, operation: RegisteredContextOperation) -> Self {
449 self.local(self.inner.facts.with_db_operation(operation))
450 }
451 pub fn in_task(&self, task: u64) -> Self {
454 self.local(self.inner.facts.with_task(ContextFact::Present(task)))
455 }
456 pub fn in_db_scope(
457 &self,
458 scope: &crate::DbScopeDiagnosticContext<Self>,
459 ) -> Result<Self, ContextConflict> {
460 let (original, identity) = scope.diagnostic_context();
461 if !self.same_request(original) {
462 return Err(ContextConflict::ForeignRoot);
463 }
464 let mut facts = self.inner.facts;
465 facts.scope = ContextFact::Present(identity);
466 Ok(self.local(facts))
467 }
468 pub fn observed_db_scope(
469 &self,
470 scope: &crate::DbScopeObservation<Self>,
471 ) -> Result<Self, ContextConflict> {
472 let (original, identity) = scope.diagnostic_context();
473 if !self.same_request(original) {
474 return Err(ContextConflict::ForeignRoot);
475 }
476 let mut facts = self.inner.facts;
477 facts.scope = ContextFact::Present(identity);
478 Ok(self.local(facts))
479 }
480 pub fn same_request(&self, other: &Self) -> bool {
481 Arc::ptr_eq(&self.inner.root, &other.inner.root)
482 }
483 pub fn same_view(&self, other: &Self) -> bool {
484 Arc::ptr_eq(&self.inner, &other.inner)
485 }
486 pub fn refresh(&self, root: &RequestRootRef) -> Result<Self, ContextConflict> {
488 if !root.same_request(self) {
489 return Err(ContextConflict::ForeignRoot);
490 }
491 Ok(Self::allocate(
492 Arc::clone(&self.inner.root),
493 self.inner.root.identity.get().is_some(),
494 self.inner.facts,
495 self.inner.child.clone(),
496 ))
497 }
498 pub fn child(
499 &self,
500 call: &CallContext,
501 request: &str,
502 route: &str,
503 attempt: u32,
504 ) -> Result<Self, ContextConflict> {
505 let identity = self.identity().ok_or(ContextConflict::ChildRelation)?;
506 if identity.trace.as_str() != call.trace_correlation_id().as_str()
507 || identity.request.as_str() != request
508 {
509 return Err(ContextConflict::ForeignRoot);
510 }
511 let parent_rpc = if let Some(child) = &self.inner.child {
512 &child.rpc
513 } else if let ContextFact::Present(rpc) = &identity.rpc {
514 rpc
515 } else {
516 return Err(ContextConflict::ChildRelation);
517 };
518 let rpc = call
519 .rpc_correlation_id()
520 .ok_or(ContextConflict::ChildRelation)?;
521 let suffix = rpc
522 .as_str()
523 .strip_prefix(parent_rpc.as_str())
524 .and_then(|s| s.strip_prefix('.'))
525 .ok_or(ContextConflict::ChildRelation)?;
526 let span = self
527 .inner
528 .child
529 .as_ref()
530 .map_or(identity.span, |child| child.span);
531 if suffix.is_empty()
532 || !suffix.bytes().all(|b| b.is_ascii_digit())
533 || span == call.span_id().as_u64()
534 || attempt == 0
535 {
536 return Err(ContextConflict::ChildRelation);
537 }
538 let child = Arc::new(ChildCall {
539 application: ContextLabel::checked(call.application().as_str())?,
540 module: ContextLabel::checked(call.module().as_str())?,
541 service: ContextLabel::checked(call.service().as_str())?,
542 operation: ContextLabel::checked(call.operation().as_str())?,
543 rpc: ContextIdentity::checked(rpc.as_str())?,
544 span: call.span_id().as_u64(),
545 route: ContextLabel::checked(route)?,
546 attempt,
547 #[cfg(test)]
548 observation: LocalObservation::create(self.inner.root.local, "child"),
549 });
550 Ok(Self::allocate(
551 Arc::clone(&self.inner.root),
552 self.inner.published,
553 self.inner.facts,
554 Some(child),
555 ))
556 }
557 fn identity(&self) -> Option<&RequestIdentityGroup> {
558 self.inner
559 .published
560 .then(|| self.inner.root.identity.get())
561 .flatten()
562 }
563}
564
565fn absent<T>(state: ContextFact<()>) -> ContextFact<T> {
566 match state {
567 ContextFact::NotApplicable => ContextFact::NotApplicable,
568 ContextFact::NotEstablished => ContextFact::NotEstablished,
569 _ => ContextFact::Unavailable,
570 }
571}
572impl Serialize for RequestExecutionView {
573 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
574 self.serialize_context(s, None)
575 }
576}
577impl Serialize for OutboundSourceContext<'_> {
578 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
579 self.view.serialize_context(s, Some(self.business_unit))
580 }
581}
582impl RequestExecutionView {
583 fn serialize_context<S: Serializer>(&self, s: S, business_unit: Option<&str>) -> Result<S::Ok, S::Error> {
584 let mut out = s.serialize_struct("RequestContext", 21 + usize::from(business_unit.is_some()))?;
585 let identity = self.identity();
586 let child = self.inner.child.as_deref();
587 let initial = self.inner.root.initial;
588 out.serialize_field("schema_version", &2u8)?;
589 out.serialize_field("local_request", &self.inner.root.local)?;
590 out.serialize_field("publication", &u8::from(self.inner.published))?;
591 out.serialize_field(
592 "application",
593 &ContextFact::Present(&self.inner.root.application),
594 )?;
595 out.serialize_field(
596 "call_application",
597 &ContextFact::Present(child.map_or(&self.inner.root.application, |c| &c.application)),
598 )?;
599 macro_rules! root_field {
600 ($name:literal, $field:ident) => {
601 out.serialize_field(
602 $name,
603 &identity.map_or_else(|| absent(initial), |g| ContextFact::Present(&g.$field)),
604 )?;
605 };
606 }
607 macro_rules! call_field {
608 ($name:literal, $field:ident) => {
609 out.serialize_field(
610 $name,
611 &child
612 .map(|c| &c.$field)
613 .or_else(|| identity.map(|g| &g.$field))
614 .map_or_else(|| absent(initial), ContextFact::Present),
615 )?;
616 };
617 }
618 call_field!("module", module);
619 call_field!("service", service);
620 call_field!("operation", operation);
621 root_field!("trace_id", trace);
622 root_field!("request", request);
623 let span = child.map(|c| c.span).or_else(|| identity.map(|g| g.span));
624 out.serialize_field(
625 "span_id",
626 &span.map_or_else(
627 || absent(initial),
628 |s| ContextFact::Present(SpanProjection(s)),
629 ),
630 )?;
631 call_field!("route", route);
632 call_field!("attempt", attempt);
633 let rpc = child
634 .map(|c| ContextFact::Present(c.rpc))
635 .or_else(|| identity.map(|g| g.rpc))
636 .unwrap_or_else(|| absent(initial));
637 out.serialize_field("rpc_id", &rpc)?;
638 out.serialize_field(
639 "zone",
640 &identity.map_or_else(|| absent(initial), |g| g.zone),
641 )?;
642 out.serialize_field("db_operation", &self.inner.facts.db_operation)?;
643 out.serialize_field("scope", &self.inner.facts.scope)?;
644 out.serialize_field("task", &self.inner.facts.task)?;
645 out.serialize_field("lifecycle", &ContextFact::Present(self.inner.facts.phase))?;
646 out.serialize_field(
648 "target",
649 &child.map_or(ContextFact::NotApplicable, |c| {
650 ContextFact::Present(&c.route)
651 }),
652 )?;
653 if let Some(business_unit) = business_unit {
654 out.serialize_field("business_unit", &ContextFact::Present(business_unit))?;
655 }
656 out.end()
657 }
658}
659
660pub fn request_context_layouts() -> [(std::alloc::Layout, std::alloc::Layout); 3] {
664 fn pair<T>() -> (std::alloc::Layout, std::alloc::Layout) {
665 let payload = std::alloc::Layout::new::<T>();
666 let header = std::alloc::Layout::new::<[std::sync::atomic::AtomicUsize; 2]>();
667 (
668 payload,
669 header
670 .extend(payload)
671 .expect("fixed layout")
672 .0
673 .pad_to_align(),
674 )
675 }
676 [
677 pair::<RequestRoot>(),
678 pair::<LocalView>(),
679 pair::<ChildCall>(),
680 ]
681}
682
683#[cfg(not(test))]
684fn observe(_: u64, _: &'static str) {}
685#[cfg(test)]
686fn observe(root: u64, event: &'static str) {
687 EVENTS.lock().unwrap().push((root, event));
688 record_observation(root, root, "root", event);
689}
690#[cfg(test)]
691static EVENTS: std::sync::Mutex<Vec<(u64, &'static str)>> = std::sync::Mutex::new(Vec::new());
692
693#[derive(Clone, Copy)]
694struct SpanProjection(u64);
695impl Serialize for SpanProjection {
696 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
697 let mut bytes = [b'0'; 16];
698 for (i, byte) in bytes.iter_mut().enumerate() {
699 *byte = b"0123456789abcdef"[((self.0 >> ((15 - i) * 4)) & 15) as usize];
700 }
701 serializer.serialize_str(std::str::from_utf8(&bytes).expect("hex"))
702 }
703}
704
705#[cfg(test)]
708struct LocalObservation {
709 id: u64,
710 root: u64,
711 kind: &'static str,
712}
713#[cfg(test)]
714static LOCAL_EVENTS: std::sync::Mutex<Vec<(u64, u64, &'static str, &'static str)>> =
715 std::sync::Mutex::new(Vec::new());
716#[cfg(test)]
717impl LocalObservation {
718 fn create(root: u64, kind: &'static str) -> Self {
719 static NEXT: AtomicU64 = AtomicU64::new(1);
720 let observation = Self {
721 id: NEXT.fetch_add(1, Ordering::Relaxed),
722 root,
723 kind,
724 };
725 observation.record("create");
726 observation
727 }
728 fn record(&self, event: &'static str) {
729 LOCAL_EVENTS
730 .lock()
731 .unwrap()
732 .push((self.id, self.root, self.kind, event));
733 record_observation(self.root, self.id, self.kind, event);
734 }
735}
736
737#[cfg(test)]
738type ObservationEvent = (u64, u64, u64, &'static str, &'static str);
739#[cfg(test)]
740static ORDERED_EVENTS: std::sync::Mutex<Vec<ObservationEvent>> = std::sync::Mutex::new(Vec::new());
741#[cfg(test)]
742fn record_observation(root: u64, object: u64, kind: &'static str, event: &'static str) {
743 static SEQUENCE: AtomicU64 = AtomicU64::new(1);
744 let sequence = SEQUENCE.fetch_add(1, Ordering::Relaxed);
745 ORDERED_EVENTS
746 .lock()
747 .unwrap()
748 .push((sequence, root, object, kind, event));
749}
750
751#[cfg(test)]
752mod tests;