@@ -6,13 +6,13 @@ use crate::Application;
6
6
use crate :: ResponseError ;
7
7
use crate :: Session ;
8
8
use async_std:: sync:: RwLock ;
9
- use chrono:: { Duration , Utc } ;
9
+ use chrono:: Utc ;
10
10
use primitives:: adapter:: Adapter ;
11
11
use primitives:: sentry:: { Event , EventAggregate } ;
12
12
use primitives:: { Channel , ChannelId } ;
13
13
use std:: collections:: HashMap ;
14
14
use std:: sync:: Arc ;
15
- use std:: time:: Duration as TimeDuration ;
15
+ use std:: time:: Duration ;
16
16
use tokio:: time:: delay_for;
17
17
18
18
#[ derive( Default , Clone ) ]
@@ -66,45 +66,54 @@ impl EventAggregator {
66
66
}
67
67
68
68
let mut recorder = self . aggregate . write ( ) . await ;
69
+ let aggr_throttle = app. config . aggr_throttle ;
70
+ let dbpool = app. pool . clone ( ) ;
71
+ let aggregate = self . aggregate . clone ( ) ;
72
+ let withdraw_period_start = channel. spec . withdraw_period_start ;
73
+ let channel_id = channel. id ;
74
+
69
75
let mut aggr: & mut EventAggregate =
70
76
if let Some ( aggr) = recorder. get_mut ( & channel. id . to_string ( ) ) {
71
77
aggr
72
78
} else {
73
79
// insert into
74
80
recorder. insert ( channel. id . to_string ( ) , new_aggr ( & channel. id ) ) ;
81
+
82
+ // spawn async task that persists
83
+ // the channel events to database
84
+ if aggr_throttle > 0 {
85
+ tokio:: spawn ( async move {
86
+ loop {
87
+ // break loop if the
88
+ // channel withdraw period has started
89
+ // since no event is allowed once a channel
90
+ // is in withdraw period
91
+
92
+ if Utc :: now ( ) > withdraw_period_start {
93
+ break ;
94
+ }
95
+
96
+ delay_for ( Duration :: from_secs ( aggr_throttle as u64 ) ) . await ;
97
+ store ( & dbpool, & channel_id, aggregate. clone ( ) ) . await ;
98
+ }
99
+ } ) ;
100
+ }
101
+
75
102
recorder
76
103
. get_mut ( & channel. id . to_string ( ) )
77
104
. expect ( "should have aggr, we just inserted" )
78
105
} ;
79
106
80
- // if aggr is none
81
107
events
82
108
. iter ( )
83
109
. for_each ( |ev| event_reducer:: reduce ( & channel, & mut aggr, ev) ) ;
84
- let created = aggr. created ;
85
- let dbpool = app. pool . clone ( ) ;
86
- let aggr_throttle = app. config . aggr_throttle ;
87
- let aggregate = self . aggregate . clone ( ) ;
88
110
89
111
// drop write access to RwLock
90
112
// this is required to prevent a deadlock in store
91
113
drop ( recorder) ;
92
114
93
- // Checks if aggr_throttle is set
94
- // and if current time is greater than aggr.created plus throttle seconds
95
- //
96
- // This approach spawns an async task every > AGGR_THROTTLE seconds
97
- // Each spawned task resolves after AGGR_THROTTLE seconds
98
- //
99
-
100
- if aggr_throttle > 0 && Utc :: now ( ) > ( created + Duration :: seconds ( aggr_throttle as i64 ) ) {
101
- // spawn a tokio task for saving to database
102
- tokio:: spawn ( async move {
103
- delay_for ( TimeDuration :: from_secs ( aggr_throttle as u64 ) ) . await ;
104
- store ( & dbpool, & channel. id , aggregate) . await ;
105
- } ) ;
106
- } else {
107
- store ( & app. pool , & channel. id , aggregate) . await ;
115
+ if aggr_throttle == 0 {
116
+ store ( & app. pool , & channel. id , self . aggregate . clone ( ) ) . await ;
108
117
}
109
118
110
119
Ok ( ( ) )
0 commit comments