@@ -159,7 +159,7 @@ impl<T: SpanExporter> SpanProcessor for SimpleSpanProcessor<T> {
159159 }
160160
161161 fn shutdown_with_timeout ( & self , timeout : Duration ) -> OTelSdkResult {
162- if let Ok ( mut exporter) = self . exporter . lock ( ) {
162+ if let Ok ( exporter) = self . exporter . lock ( ) {
163163 exporter. shutdown_with_timeout ( timeout)
164164 } else {
165165 Err ( OTelSdkError :: InternalFailure (
@@ -1089,7 +1089,7 @@ mod tests {
10891089 Ok ( ( ) )
10901090 }
10911091
1092- fn shutdown ( & mut self ) -> OTelSdkResult {
1092+ fn shutdown ( & self ) -> OTelSdkResult {
10931093 Ok ( ( ) )
10941094 }
10951095 fn set_resource ( & mut self , resource : & Resource ) {
@@ -1373,4 +1373,68 @@ mod tests {
13731373 let exported_spans = exporter_shared. lock ( ) . unwrap ( ) ;
13741374 assert_eq ! ( exported_spans. len( ) , 10 ) ;
13751375 }
1376+
1377+ #[ test]
1378+ fn test_span_exporter_immutable_reference ( ) {
1379+ use std:: sync:: atomic:: { AtomicBool , Ordering } ;
1380+ use crate :: error:: OTelSdkError ;
1381+
1382+ // Simple test exporter that demonstrates the &self pattern
1383+ #[ derive( Debug ) ]
1384+ struct TestExporter {
1385+ is_shutdown : AtomicBool ,
1386+ }
1387+
1388+ impl TestExporter {
1389+ fn new ( ) -> Self {
1390+ Self {
1391+ is_shutdown : AtomicBool :: new ( false ) ,
1392+ }
1393+ }
1394+
1395+ fn is_shutdown ( & self ) -> bool {
1396+ self . is_shutdown . load ( Ordering :: Relaxed )
1397+ }
1398+ }
1399+
1400+ impl SpanExporter for TestExporter {
1401+ async fn export ( & self , _batch : Vec < SpanData > ) -> OTelSdkResult {
1402+ if self . is_shutdown ( ) {
1403+ return Err ( OTelSdkError :: AlreadyShutdown ) ;
1404+ }
1405+ Ok ( ( ) )
1406+ }
1407+
1408+ fn shutdown ( & self ) -> OTelSdkResult {
1409+ self . is_shutdown . store ( true , Ordering :: Relaxed ) ;
1410+ Ok ( ( ) )
1411+ }
1412+
1413+ fn shutdown_with_timeout ( & self , _timeout : Duration ) -> OTelSdkResult {
1414+ self . shutdown ( )
1415+ }
1416+
1417+ fn force_flush ( & self ) -> OTelSdkResult {
1418+ Ok ( ( ) )
1419+ }
1420+ }
1421+
1422+ let exporter = TestExporter :: new ( ) ;
1423+
1424+ // These methods now work with &self
1425+ assert ! ( !exporter. is_shutdown( ) ) ;
1426+
1427+ let result = exporter. shutdown ( ) ;
1428+ assert ! ( result. is_ok( ) ) ;
1429+
1430+ assert ! ( exporter. is_shutdown( ) ) ;
1431+
1432+ // Test that export fails after shutdown
1433+ let export_result = futures_executor:: block_on ( exporter. export ( vec ! [ ] ) ) ;
1434+ assert ! ( export_result. is_err( ) ) ;
1435+
1436+ // Test force_flush
1437+ let flush_result = exporter. force_flush ( ) ;
1438+ assert ! ( flush_result. is_ok( ) ) ;
1439+ }
13761440}
0 commit comments