Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions sentry-core/src/hub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,17 +427,14 @@ impl Hub {
if let Some(ref client) = top.client {
let scope = Arc::make_mut(&mut top.scope);
let options = client.options();
let breadcrumbs = Arc::make_mut(&mut scope.breadcrumbs);
for breadcrumb in breadcrumb.into_breadcrumbs() {
let breadcrumb_opt = match options.before_breadcrumb {
Some(ref callback) => callback(breadcrumb),
None => Some(breadcrumb)
};

if let Some(breadcrumb) = breadcrumb_opt {
breadcrumbs.push_back(breadcrumb);
}
while breadcrumbs.len() > options.max_breadcrumbs {
breadcrumbs.pop_front();
scope.add_breadcrumb(breadcrumb, options.max_breadcrumbs);
}
}
}
Expand Down
49 changes: 49 additions & 0 deletions sentry-core/src/scope/real.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,24 @@ use crate::protocol::{Attachment, Breadcrumb, Context, Event, Level, User, Value
use crate::session::Session;
use crate::Client;

#[non_exhaustive]
pub enum ScopeUpdate {
AddBreadcrumb(Breadcrumb),
ClearBreadcrumbs,
User(Option<User>),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
User(Option<User>),
SetUser(Option<User>),

SetExtra(String, Value),
RemoveExtra(String),
SetTag(String, String),
RemoveTag(String),
}

#[derive(Debug)]
pub struct Stack {
layers: Vec<StackLayer>,
}

pub type EventProcessor = Arc<dyn Fn(Event<'static>) -> Option<Event<'static>> + Send + Sync>;
pub type ScopeListener = Arc<dyn Fn(&ScopeUpdate) + Send + Sync>;

/// Holds contextual data for the current scope.
///
Expand Down Expand Up @@ -44,6 +56,7 @@ pub struct Scope {
pub(crate) tags: Arc<HashMap<String, String>>,
pub(crate) contexts: Arc<HashMap<String, Context>>,
pub(crate) event_processors: Arc<Vec<EventProcessor>>,
pub(crate) scope_listeners: Arc<Vec<ScopeListener>>,
pub(crate) session: Arc<Mutex<Option<Session>>>,
pub(crate) span: Arc<Option<TransactionOrSpan>>,
pub(crate) attachments: Arc<Vec<Attachment>>,
Expand Down Expand Up @@ -146,6 +159,7 @@ impl Scope {

/// Deletes current breadcrumbs from the scope.
pub fn clear_breadcrumbs(&mut self) {
self.notify_scope_listeners(|| ScopeUpdate::ClearBreadcrumbs);
self.breadcrumbs = Default::default();
}

Expand Down Expand Up @@ -178,18 +192,21 @@ impl Scope {

/// Sets the user for the current scope.
pub fn set_user(&mut self, user: Option<User>) {
self.notify_scope_listeners(|| ScopeUpdate::User(user.clone()));
self.user = user.map(Arc::new);
}

/// Sets a tag to a specific value.
pub fn set_tag<V: ToString>(&mut self, key: &str, value: V) {
self.notify_scope_listeners(|| ScopeUpdate::SetTag(key.to_string(), value.to_string()));
Arc::make_mut(&mut self.tags).insert(key.to_string(), value.to_string());
}

/// Removes a tag.
///
/// If the tag is not set, does nothing.
pub fn remove_tag(&mut self, key: &str) {
self.notify_scope_listeners(|| ScopeUpdate::RemoveTag(key.to_string()));
Arc::make_mut(&mut self.tags).remove(key);
}

Expand All @@ -205,11 +222,13 @@ impl Scope {

/// Sets a extra to a specific value.
pub fn set_extra(&mut self, key: &str, value: Value) {
self.notify_scope_listeners(|| ScopeUpdate::SetExtra(key.to_string(), value.clone()));
Arc::make_mut(&mut self.extra).insert(key.to_string(), value);
}

/// Removes a extra.
pub fn remove_extra(&mut self, key: &str) {
self.notify_scope_listeners(|| ScopeUpdate::RemoveExtra(key.to_string()));
Arc::make_mut(&mut self.extra).remove(key);
}

Expand All @@ -221,6 +240,14 @@ impl Scope {
Arc::make_mut(&mut self.event_processors).push(Arc::new(f));
}

/// Add an scope listener to the scope.
pub fn add_scope_listener<F>(&mut self, f: F)
where
F: Fn(&ScopeUpdate) + Send + Sync + 'static,
{
Arc::make_mut(&mut self.scope_listeners).push(Arc::new(f));
}

/// Adds an attachment to the scope
pub fn add_attachment(&mut self, attachment: Attachment) {
Arc::make_mut(&mut self.attachments).push(attachment);
Expand Down Expand Up @@ -304,4 +331,26 @@ impl Scope {
session.update_from_event(event);
}
}

pub(crate) fn add_breadcrumb(&mut self, breadcrumb: Breadcrumb, max_breadcrumbs: usize) {
self.notify_scope_listeners(|| ScopeUpdate::AddBreadcrumb(breadcrumb.clone()));

let breadcrumbs = Arc::make_mut(&mut self.breadcrumbs);
breadcrumbs.push_back(breadcrumb);

while breadcrumbs.len() > max_breadcrumbs {
breadcrumbs.pop_front();
}
}

fn notify_scope_listeners<F: Fn() -> ScopeUpdate>(&mut self, update_fn: F) {
if self.scope_listeners.is_empty() {
return;
}

let update = update_fn();
for listener in self.scope_listeners.as_ref() {
listener(&update);
}
}
}