@@ -4,6 +4,7 @@ use std::env;
4
4
use std:: ffi:: { OsStr , OsString } ;
5
5
use std:: fmt;
6
6
use std:: sync:: Arc ;
7
+ use std:: sync:: RwLock ;
7
8
use std:: time:: Duration ;
8
9
9
10
use rand:: random;
@@ -21,10 +22,9 @@ use transport::{DefaultTransportFactory, Transport, TransportFactory};
21
22
use utils:: { debug_images, server_name} ;
22
23
23
24
/// The Sentry client object.
24
- #[ derive( Clone ) ]
25
25
pub struct Client {
26
26
options : ClientOptions ,
27
- transport : Option < Arc < Box < Transport > > > ,
27
+ transport : RwLock < Option < Arc < Box < Transport > > > > ,
28
28
}
29
29
30
30
impl fmt:: Debug for Client {
@@ -36,6 +36,15 @@ impl fmt::Debug for Client {
36
36
}
37
37
}
38
38
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
+
39
48
/// Type alias for before event/breadcrumb handlers.
40
49
pub type BeforeCallback < T > = Arc < Box < Fn ( T ) -> Option < T > + Send + Sync > > ;
41
50
@@ -81,8 +90,8 @@ pub struct ClientOptions {
81
90
/// This will default to the `HTTPS_PROXY` environment variable
82
91
/// or `http_proxy` if that one exists.
83
92
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 ,
86
95
/// Attaches stacktraces to messages.
87
96
pub attach_stacktrace : bool ,
88
97
/// If turned on some default PII informat is attached.
@@ -185,7 +194,7 @@ impl Default for ClientOptions {
185
194
. map ( Cow :: Owned )
186
195
. or_else ( || env:: var ( "HTTPS_PROXY" ) . ok ( ) . map ( Cow :: Owned ) )
187
196
. 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 ) ,
189
198
attach_stacktrace : false ,
190
199
send_default_pii : false ,
191
200
before_send : None ,
@@ -338,11 +347,11 @@ impl Client {
338
347
/// disabled.
339
348
pub fn with_options ( options : ClientOptions ) -> Client {
340
349
#[ 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 ( ) {
342
351
None
343
352
} else {
344
353
Some ( Arc :: new ( options. transport . create_transport ( & options) ) )
345
- } ;
354
+ } ) ;
346
355
Client { options, transport }
347
356
}
348
357
@@ -364,7 +373,7 @@ impl Client {
364
373
pub fn disabled_with_options ( options : ClientOptions ) -> Client {
365
374
Client {
366
375
options,
367
- transport : None ,
376
+ transport : RwLock :: new ( None ) ,
368
377
}
369
378
}
370
379
@@ -517,7 +526,7 @@ impl Client {
517
526
518
527
/// Captures an event and sends it to sentry.
519
528
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 ( ) {
521
530
if self . sample_should_send ( ) {
522
531
if let Some ( event) = self . prepare_event ( event, scope) {
523
532
let event_id = event. id . unwrap ( ) ;
@@ -529,14 +538,16 @@ impl Client {
529
538
Default :: default ( )
530
539
}
531
540
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.
533
543
///
534
544
/// This returns `true` if the queue was successfully drained in the
535
545
/// 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 ) )
540
551
} else {
541
552
true
542
553
}
@@ -559,7 +570,7 @@ pub struct ClientInitGuard(Arc<Client>);
559
570
560
571
impl Drop for ClientInitGuard {
561
572
fn drop ( & mut self ) {
562
- self . 0 . drain_events ( self . 0 . options . shutdown_timeout ) ;
573
+ self . 0 . close ( None ) ;
563
574
}
564
575
}
565
576
0 commit comments