@@ -4,6 +4,7 @@ use std::env;
44use std:: ffi:: { OsStr , OsString } ;
55use std:: fmt;
66use std:: sync:: Arc ;
7+ use std:: sync:: RwLock ;
78use std:: time:: Duration ;
89
910use rand:: random;
@@ -21,10 +22,9 @@ use transport::{DefaultTransportFactory, Transport, TransportFactory};
2122use utils:: { debug_images, server_name} ;
2223
2324/// The Sentry client object.
24- #[ derive( Clone ) ]
2525pub struct Client {
2626 options : ClientOptions ,
27- transport : Option < Arc < Box < Transport > > > ,
27+ transport : RwLock < Option < Arc < Box < Transport > > > > ,
2828}
2929
3030impl fmt:: Debug for Client {
@@ -36,6 +36,15 @@ impl fmt::Debug for Client {
3636 }
3737}
3838
39+ impl Clone for Client {
40+ fn clone ( & self ) -> Client {
41+ Client {
42+ options : self . options . clone ( ) ,
43+ transport : RwLock :: new ( self . transport . read ( ) . unwrap ( ) . clone ( ) ) ,
44+ }
45+ }
46+ }
47+
3948/// Type alias for before event/breadcrumb handlers.
4049pub type BeforeCallback < T > = Arc < Box < Fn ( T ) -> Option < T > + Send + Sync > > ;
4150
@@ -81,8 +90,8 @@ pub struct ClientOptions {
8190 /// This will default to the `HTTPS_PROXY` environment variable
8291 /// or `http_proxy` if that one exists.
8392 pub https_proxy : Option < Cow < ' static , str > > ,
84- /// The timeout on client drop for draining events.
85- pub shutdown_timeout : Option < Duration > ,
93+ /// The timeout on client drop for draining events on shutdown .
94+ pub shutdown_timeout : Duration ,
8695 /// Attaches stacktraces to messages.
8796 pub attach_stacktrace : bool ,
8897 /// If turned on some default PII informat is attached.
@@ -185,7 +194,7 @@ impl Default for ClientOptions {
185194 . map ( Cow :: Owned )
186195 . or_else ( || env:: var ( "HTTPS_PROXY" ) . ok ( ) . map ( Cow :: Owned ) )
187196 . or_else ( || env:: var ( "http_proxy" ) . ok ( ) . map ( Cow :: Owned ) ) ,
188- shutdown_timeout : Some ( Duration :: from_secs ( 2 ) ) ,
197+ shutdown_timeout : Duration :: from_secs ( 2 ) ,
189198 attach_stacktrace : false ,
190199 send_default_pii : false ,
191200 before_send : None ,
@@ -338,11 +347,11 @@ impl Client {
338347 /// disabled.
339348 pub fn with_options ( options : ClientOptions ) -> Client {
340349 #[ cfg_attr( feature = "cargo-clippy" , allow( question_mark) ) ]
341- let transport = if options. dsn . is_none ( ) {
350+ let transport = RwLock :: new ( if options. dsn . is_none ( ) {
342351 None
343352 } else {
344353 Some ( Arc :: new ( options. transport . create_transport ( & options) ) )
345- } ;
354+ } ) ;
346355 Client { options, transport }
347356 }
348357
@@ -364,7 +373,7 @@ impl Client {
364373 pub fn disabled_with_options ( options : ClientOptions ) -> Client {
365374 Client {
366375 options,
367- transport : None ,
376+ transport : RwLock :: new ( None ) ,
368377 }
369378 }
370379
@@ -517,7 +526,7 @@ impl Client {
517526
518527 /// Captures an event and sends it to sentry.
519528 pub fn capture_event ( & self , event : Event < ' static > , scope : Option < & Scope > ) -> Uuid {
520- if let Some ( ref transport) = self . transport {
529+ if let Some ( ref transport) = * self . transport . read ( ) . unwrap ( ) {
521530 if self . sample_should_send ( ) {
522531 if let Some ( event) = self . prepare_event ( event, scope) {
523532 let event_id = event. id . unwrap ( ) ;
@@ -529,14 +538,16 @@ impl Client {
529538 Default :: default ( )
530539 }
531540
532- /// Drains all pending events up to the current time.
541+ /// Drains all pending events and shuts down the transport behind the
542+ /// client. After shutting down the transport is removed.
533543 ///
534544 /// This returns `true` if the queue was successfully drained in the
535545 /// given time or `false` if not (for instance because of a timeout).
536- /// If no timeout is provided the client will wait forever.
537- pub fn drain_events ( & self , timeout : Option < Duration > ) -> bool {
538- if let Some ( ref transport) = self . transport {
539- transport. drain ( timeout)
546+ /// If no timeout is provided the client will wait for as long a
547+ /// `shutdown_timeout` in the client options.
548+ pub fn close ( & self , timeout : Option < Duration > ) -> bool {
549+ if let Some ( transport) = self . transport . write ( ) . unwrap ( ) . take ( ) {
550+ transport. shutdown ( timeout. unwrap_or ( self . options . shutdown_timeout ) )
540551 } else {
541552 true
542553 }
@@ -559,7 +570,7 @@ pub struct ClientInitGuard(Arc<Client>);
559570
560571impl Drop for ClientInitGuard {
561572 fn drop ( & mut self ) {
562- self . 0 . drain_events ( self . 0 . options . shutdown_timeout ) ;
573+ self . 0 . close ( None ) ;
563574 }
564575}
565576
0 commit comments