@@ -103,16 +103,6 @@ pub struct StoreMetrics {
103103 pub retention : u16 ,
104104}
105105
106- /// Publishes session metric buckets to EAP via the snuba-items topic.
107- ///
108- /// Used when the `UserSessionsEap` feature flag is enabled for double-write.
109- #[ derive( Clone , Debug ) ]
110- pub struct StoreSessionMetricsEap {
111- pub buckets : Vec < Bucket > ,
112- pub scoping : Scoping ,
113- pub retention : u16 ,
114- }
115-
116106/// Publishes a log item to the Sentry core application through Kafka.
117107#[ derive( Debug ) ]
118108pub struct StoreTraceItem {
@@ -185,8 +175,6 @@ pub enum Store {
185175 Envelope ( StoreEnvelope ) ,
186176 /// Aggregated generic metrics.
187177 Metrics ( StoreMetrics ) ,
188- /// Session metrics routed to EAP (Event Analytics Platform).
189- SessionMetricsEap ( StoreSessionMetricsEap ) ,
190178 /// A singular [`TraceItem`].
191179 TraceItem ( Managed < StoreTraceItem > ) ,
192180 /// A singular Span.
@@ -201,7 +189,6 @@ impl Store {
201189 match self {
202190 Store :: Envelope ( _) => "envelope" ,
203191 Store :: Metrics ( _) => "metrics" ,
204- Store :: SessionMetricsEap ( _) => "session_metrics_eap" ,
205192 Store :: TraceItem ( _) => "log" ,
206193 Store :: Span ( _) => "span" ,
207194 Store :: ProfileChunk ( _) => "profile_chunk" ,
@@ -227,14 +214,6 @@ impl FromMessage<StoreMetrics> for Store {
227214 }
228215}
229216
230- impl FromMessage < StoreSessionMetricsEap > for Store {
231- type Response = NoResponse ;
232-
233- fn from_message ( message : StoreSessionMetricsEap , _: ( ) ) -> Self {
234- Self :: SessionMetricsEap ( message)
235- }
236- }
237-
238217impl FromMessage < Managed < StoreTraceItem > > for Store {
239218 type Response = NoResponse ;
240219
@@ -294,7 +273,6 @@ impl StoreService {
294273 match message {
295274 Store :: Envelope ( message) => self . handle_store_envelope( message) ,
296275 Store :: Metrics ( message) => self . handle_store_metrics( message) ,
297- Store :: SessionMetricsEap ( message) => self . handle_store_session_metrics_eap( message) ,
298276 Store :: TraceItem ( message) => self . handle_store_trace_item( message) ,
299277 Store :: Span ( message) => self . handle_store_span( message) ,
300278 Store :: ProfileChunk ( message) => self . handle_store_profile_chunk( message) ,
@@ -543,9 +521,22 @@ impl StoreService {
543521 let global_config = self . global_config . current ( ) ;
544522 let mut encoder = BucketEncoder :: new ( & global_config) ;
545523
524+ // Check if this organization is rolled out for sessions EAP double-write.
525+ let sessions_eap_rollout_rate = global_config. options . sessions_eap_rollout_rate ;
526+ let emit_sessions_to_eap =
527+ utils:: is_rolled_out ( scoping. organization_id . value ( ) , sessions_eap_rollout_rate)
528+ . is_keep ( ) ;
529+
546530 let now = UnixTimestamp :: now ( ) ;
547531 let mut delay_stats = ByNamespace :: < ( u64 , u64 , u64 ) > :: default ( ) ;
548532
533+ // Collect session buckets for EAP if rolled out.
534+ let mut session_buckets = if emit_sessions_to_eap {
535+ Vec :: new ( )
536+ } else {
537+ Vec :: with_capacity ( 0 )
538+ } ;
539+
549540 for mut bucket in buckets {
550541 let namespace = encoder. prepare ( & mut bucket) ;
551542
@@ -557,6 +548,11 @@ impl StoreService {
557548 * max = ( * max) . max ( delay) ;
558549 }
559550
551+ // Collect session buckets for EAP double-write.
552+ if emit_sessions_to_eap && namespace == MetricNamespace :: Sessions {
553+ session_buckets. push ( bucket. clone ( ) ) ;
554+ }
555+
560556 // Create a local bucket view to avoid splitting buckets unnecessarily. Since we produce
561557 // each bucket separately, we only need to split buckets that exceed the size, but not
562558 // batches.
@@ -588,6 +584,11 @@ impl StoreService {
588584 }
589585 }
590586
587+ // Also emit session buckets to EAP if rolled out.
588+ if !session_buckets. is_empty ( ) {
589+ self . emit_session_metrics_to_eap ( & session_buckets, scoping, retention) ;
590+ }
591+
591592 if let Some ( error) = error {
592593 relay_log:: error!(
593594 error = & error as & dyn std:: error:: Error ,
@@ -614,8 +615,11 @@ impl StoreService {
614615 }
615616 }
616617
617- /// Sends session metric buckets to EAP (snuba-items topic) as TraceItems.
618- fn handle_store_session_metrics_eap ( & self , message : StoreSessionMetricsEap ) {
618+ /// Emits session metric buckets to EAP (snuba-items topic) as TraceItems.
619+ ///
620+ /// This is called when the organization is rolled out for sessions EAP double-write
621+ /// via `sessions_eap_rollout_rate`.
622+ fn emit_session_metrics_to_eap ( & self , buckets : & [ Bucket ] , scoping : Scoping , retention : u16 ) {
619623 use sentry_protos:: snuba:: v1:: { AnyValue , TraceItem , TraceItemType , any_value} ;
620624 use std:: collections:: HashMap ;
621625
@@ -624,11 +628,6 @@ impl StoreService {
624628 0x90 , 0xa1 ,
625629 ] ) ;
626630
627- let StoreSessionMetricsEap {
628- buckets,
629- scoping,
630- retention,
631- } = message;
632631 let now = UnixTimestamp :: now ( ) ;
633632 let mut error = None ;
634633 let mut row_count: u64 = 0 ;
@@ -696,8 +695,8 @@ impl StoreService {
696695 trace_id : uuid. to_string ( ) ,
697696 item_id : uuid. as_bytes ( ) [ ..16 ] . into ( ) ,
698697 item_type : i32:: from ( TraceItemType :: UserSession ) ,
699- timestamp : timestamp . clone ( ) ,
700- received : received . clone ( ) ,
698+ timestamp,
699+ received,
701700 retention_days : retention. into ( ) ,
702701 downsampled_retention_days : retention. into ( ) ,
703702 attributes,
0 commit comments