@@ -8,12 +8,24 @@ use crate::protocol::{Attachment, Breadcrumb, Context, Event, Level, User, Value
88use crate :: session:: Session ;
99use crate :: Client ;
1010
11+ #[ non_exhaustive]
12+ pub enum ScopeUpdate {
13+ AddBreadcrumb ( Breadcrumb ) ,
14+ ClearBreadcrumbs ,
15+ User ( Option < User > ) ,
16+ SetExtra ( String , Value ) ,
17+ RemoveExtra ( String ) ,
18+ SetTag ( String , String ) ,
19+ RemoveTag ( String ) ,
20+ }
21+
1122#[ derive( Debug ) ]
1223pub struct Stack {
1324 layers : Vec < StackLayer > ,
1425}
1526
1627pub type EventProcessor = Arc < dyn Fn ( Event < ' static > ) -> Option < Event < ' static > > + Send + Sync > ;
28+ pub type ScopeListener = Arc < dyn Fn ( & ScopeUpdate ) + Send + Sync > ;
1729
1830/// Holds contextual data for the current scope.
1931///
@@ -44,6 +56,7 @@ pub struct Scope {
4456 pub ( crate ) tags : Arc < HashMap < String , String > > ,
4557 pub ( crate ) contexts : Arc < HashMap < String , Context > > ,
4658 pub ( crate ) event_processors : Arc < Vec < EventProcessor > > ,
59+ pub ( crate ) scope_listeners : Arc < Vec < ScopeListener > > ,
4760 pub ( crate ) session : Arc < Mutex < Option < Session > > > ,
4861 pub ( crate ) span : Arc < Option < TransactionOrSpan > > ,
4962 pub ( crate ) attachments : Arc < Vec < Attachment > > ,
@@ -144,6 +157,7 @@ impl Scope {
144157
145158 /// Deletes current breadcrumbs from the scope.
146159 pub fn clear_breadcrumbs ( & mut self ) {
160+ self . notify_scope_listeners ( || ScopeUpdate :: ClearBreadcrumbs ) ;
147161 self . breadcrumbs = Default :: default ( ) ;
148162 }
149163
@@ -176,18 +190,21 @@ impl Scope {
176190
177191 /// Sets the user for the current scope.
178192 pub fn set_user ( & mut self , user : Option < User > ) {
193+ self . notify_scope_listeners ( || ScopeUpdate :: User ( user. clone ( ) ) ) ;
179194 self . user = user. map ( Arc :: new) ;
180195 }
181196
182197 /// Sets a tag to a specific value.
183198 pub fn set_tag < V : ToString > ( & mut self , key : & str , value : V ) {
199+ self . notify_scope_listeners ( || ScopeUpdate :: SetTag ( key. to_string ( ) , value. to_string ( ) ) ) ;
184200 Arc :: make_mut ( & mut self . tags ) . insert ( key. to_string ( ) , value. to_string ( ) ) ;
185201 }
186202
187203 /// Removes a tag.
188204 ///
189205 /// If the tag is not set, does nothing.
190206 pub fn remove_tag ( & mut self , key : & str ) {
207+ self . notify_scope_listeners ( || ScopeUpdate :: RemoveTag ( key. to_string ( ) ) ) ;
191208 Arc :: make_mut ( & mut self . tags ) . remove ( key) ;
192209 }
193210
@@ -203,11 +220,13 @@ impl Scope {
203220
204221 /// Sets a extra to a specific value.
205222 pub fn set_extra ( & mut self , key : & str , value : Value ) {
223+ self . notify_scope_listeners ( || ScopeUpdate :: SetExtra ( key. to_string ( ) , value. clone ( ) ) ) ;
206224 Arc :: make_mut ( & mut self . extra ) . insert ( key. to_string ( ) , value) ;
207225 }
208226
209227 /// Removes a extra.
210228 pub fn remove_extra ( & mut self , key : & str ) {
229+ self . notify_scope_listeners ( || ScopeUpdate :: RemoveExtra ( key. to_string ( ) ) ) ;
211230 Arc :: make_mut ( & mut self . extra ) . remove ( key) ;
212231 }
213232
@@ -219,6 +238,14 @@ impl Scope {
219238 Arc :: make_mut ( & mut self . event_processors ) . push ( Arc :: new ( f) ) ;
220239 }
221240
241+ /// Add an scope listener to the scope.
242+ pub fn add_scope_listener < F > ( & mut self , f : F )
243+ where
244+ F : Fn ( & ScopeUpdate ) + Send + Sync + ' static ,
245+ {
246+ Arc :: make_mut ( & mut self . scope_listeners ) . push ( Arc :: new ( f) ) ;
247+ }
248+
222249 /// Adds an attachment to the scope
223250 pub fn add_attachment ( & mut self , attachment : Attachment ) {
224251 Arc :: make_mut ( & mut self . attachments ) . push ( attachment) ;
@@ -302,4 +329,26 @@ impl Scope {
302329 session. update_from_event ( event) ;
303330 }
304331 }
332+
333+ pub ( crate ) fn add_breadcrumb ( & mut self , breadcrumb : Breadcrumb , max_breadcrumbs : usize ) {
334+ self . notify_scope_listeners ( || ScopeUpdate :: AddBreadcrumb ( breadcrumb. clone ( ) ) ) ;
335+
336+ let breadcrumbs = Arc :: make_mut ( & mut self . breadcrumbs ) ;
337+ breadcrumbs. push_back ( breadcrumb) ;
338+
339+ while breadcrumbs. len ( ) > max_breadcrumbs {
340+ breadcrumbs. pop_front ( ) ;
341+ }
342+ }
343+
344+ fn notify_scope_listeners < F : Fn ( ) -> ScopeUpdate > ( & mut self , update_fn : F ) {
345+ if self . scope_listeners . is_empty ( ) {
346+ return ;
347+ }
348+
349+ let update = update_fn ( ) ;
350+ for listener in self . scope_listeners . as_ref ( ) {
351+ listener ( & update) ;
352+ }
353+ }
305354}
0 commit comments