@@ -13,12 +13,12 @@ crate::pg_enum! {
13
13
}
14
14
15
15
#[ derive( Debug , Clone , Copy ) ]
16
- pub struct PublishRateLimit {
16
+ pub struct RateLimiter {
17
17
pub rate : Duration ,
18
18
pub burst : i32 ,
19
19
}
20
20
21
- impl Default for PublishRateLimit {
21
+ impl Default for RateLimiter {
22
22
fn default ( ) -> Self {
23
23
let minutes = dotenv:: var ( "WEB_NEW_PKG_RATE_LIMIT_RATE_MINUTES" )
24
24
. unwrap_or_default ( )
@@ -37,9 +37,9 @@ impl Default for PublishRateLimit {
37
37
}
38
38
}
39
39
40
- impl PublishRateLimit {
41
- pub fn check_rate_limit ( & self , uploader : i32 , conn : & PgConnection ) -> AppResult < ( ) > {
42
- let bucket = self . take_token ( uploader , Utc :: now ( ) . naive_utc ( ) , conn) ?;
40
+ impl RateLimiter {
41
+ pub fn check_rate_limit ( & self , user_id : i32 , conn : & PgConnection ) -> AppResult < ( ) > {
42
+ let bucket = self . take_token ( user_id , Utc :: now ( ) . naive_utc ( ) , conn) ?;
43
43
if bucket. tokens >= 1 {
44
44
Ok ( ( ) )
45
45
} else {
@@ -59,11 +59,10 @@ impl PublishRateLimit {
59
59
/// since we only refill buckets when trying to take a token from it.
60
60
fn take_token (
61
61
& self ,
62
- uploader : i32 ,
62
+ user_id : i32 ,
63
63
now : NaiveDateTime ,
64
64
conn : & PgConnection ,
65
65
) -> QueryResult < Bucket > {
66
- use self :: publish_limit_buckets:: dsl:: * ;
67
66
use diesel:: sql_types:: { Double , Interval , Text , Timestamp } ;
68
67
69
68
sql_function ! ( fn date_part( x: Text , y: Timestamp ) -> Double ) ;
@@ -76,7 +75,7 @@ impl PublishRateLimit {
76
75
sql_function ! ( fn least<T >( x: T , y: T ) -> T ) ;
77
76
78
77
let burst: i32 = publish_rate_overrides:: table
79
- . find ( ( uploader , LimitedAction :: PublishNew ) )
78
+ . find ( ( user_id , LimitedAction :: PublishNew ) )
80
79
. filter (
81
80
publish_rate_overrides:: expires_at
82
81
. is_null ( )
@@ -91,18 +90,25 @@ impl PublishRateLimit {
91
90
// However, for the intervals we're dealing with, it is always well
92
91
// defined, so we convert to an f64 of seconds to represent this.
93
92
let tokens_to_add = floor (
94
- ( date_part ( "epoch" , now) - date_part ( "epoch" , last_refill) )
93
+ ( date_part ( "epoch" , now) - date_part ( "epoch" , publish_limit_buckets :: last_refill) )
95
94
/ interval_part ( "epoch" , self . refill_rate ( ) ) ,
96
95
) ;
97
96
98
- diesel:: insert_into ( publish_limit_buckets)
99
- . values ( ( user_id. eq ( uploader) , tokens. eq ( burst) , last_refill. eq ( now) ) )
100
- . on_conflict ( user_id)
97
+ diesel:: insert_into ( publish_limit_buckets:: table)
98
+ . values ( (
99
+ publish_limit_buckets:: user_id. eq ( user_id) ,
100
+ publish_limit_buckets:: tokens. eq ( burst) ,
101
+ publish_limit_buckets:: last_refill. eq ( now) ,
102
+ ) )
103
+ . on_conflict ( publish_limit_buckets:: user_id)
101
104
. do_update ( )
102
105
. set ( (
103
- tokens. eq ( least ( burst, greatest ( 0 , tokens - 1 ) + tokens_to_add) ) ,
104
- last_refill
105
- . eq ( last_refill + self . refill_rate ( ) . into_sql :: < Interval > ( ) * tokens_to_add) ,
106
+ publish_limit_buckets:: tokens. eq ( least (
107
+ burst,
108
+ greatest ( 0 , publish_limit_buckets:: tokens - 1 ) + tokens_to_add,
109
+ ) ) ,
110
+ publish_limit_buckets:: last_refill. eq ( publish_limit_buckets:: last_refill
111
+ + self . refill_rate ( ) . into_sql :: < Interval > ( ) * tokens_to_add) ,
106
112
) )
107
113
. get_result ( conn)
108
114
}
@@ -134,7 +140,7 @@ mod tests {
134
140
let conn = pg_connection ( ) ;
135
141
let now = now ( ) ;
136
142
137
- let rate = PublishRateLimit {
143
+ let rate = RateLimiter {
138
144
rate : Duration :: from_secs ( 1 ) ,
139
145
burst : 10 ,
140
146
} ;
@@ -147,7 +153,7 @@ mod tests {
147
153
} ;
148
154
assert_eq ! ( expected, bucket) ;
149
155
150
- let rate = PublishRateLimit {
156
+ let rate = RateLimiter {
151
157
rate : Duration :: from_millis ( 50 ) ,
152
158
burst : 20 ,
153
159
} ;
@@ -167,7 +173,7 @@ mod tests {
167
173
let conn = pg_connection ( ) ;
168
174
let now = now ( ) ;
169
175
170
- let rate = PublishRateLimit {
176
+ let rate = RateLimiter {
171
177
rate : Duration :: from_secs ( 1 ) ,
172
178
burst : 10 ,
173
179
} ;
@@ -188,7 +194,7 @@ mod tests {
188
194
let conn = pg_connection ( ) ;
189
195
let now = now ( ) ;
190
196
191
- let rate = PublishRateLimit {
197
+ let rate = RateLimiter {
192
198
rate : Duration :: from_secs ( 1 ) ,
193
199
burst : 10 ,
194
200
} ;
@@ -214,7 +220,7 @@ mod tests {
214
220
NaiveDateTime :: parse_from_str ( "2019-03-19T21:11:24.620401" , "%Y-%m-%dT%H:%M:%S%.f" )
215
221
. unwrap ( ) ;
216
222
217
- let rate = PublishRateLimit {
223
+ let rate = RateLimiter {
218
224
rate : Duration :: from_millis ( 100 ) ,
219
225
burst : 10 ,
220
226
} ;
@@ -236,7 +242,7 @@ mod tests {
236
242
let conn = pg_connection ( ) ;
237
243
let now = now ( ) ;
238
244
239
- let rate = PublishRateLimit {
245
+ let rate = RateLimiter {
240
246
rate : Duration :: from_millis ( 100 ) ,
241
247
burst : 10 ,
242
248
} ;
@@ -258,7 +264,7 @@ mod tests {
258
264
let conn = pg_connection ( ) ;
259
265
let now = now ( ) ;
260
266
261
- let rate = PublishRateLimit {
267
+ let rate = RateLimiter {
262
268
rate : Duration :: from_secs ( 1 ) ,
263
269
burst : 10 ,
264
270
} ;
@@ -282,7 +288,7 @@ mod tests {
282
288
let conn = pg_connection ( ) ;
283
289
let now = now ( ) ;
284
290
285
- let rate = PublishRateLimit {
291
+ let rate = RateLimiter {
286
292
rate : Duration :: from_secs ( 1 ) ,
287
293
burst : 10 ,
288
294
} ;
@@ -305,7 +311,7 @@ mod tests {
305
311
let conn = pg_connection ( ) ;
306
312
let now = now ( ) ;
307
313
308
- let rate = PublishRateLimit {
314
+ let rate = RateLimiter {
309
315
rate : Duration :: from_secs ( 1 ) ,
310
316
burst : 10 ,
311
317
} ;
@@ -328,7 +334,7 @@ mod tests {
328
334
let conn = pg_connection ( ) ;
329
335
let now = now ( ) ;
330
336
331
- let rate = PublishRateLimit {
337
+ let rate = RateLimiter {
332
338
rate : Duration :: from_secs ( 1 ) ,
333
339
burst : 10 ,
334
340
} ;
@@ -355,7 +361,7 @@ mod tests {
355
361
let conn = pg_connection ( ) ;
356
362
let now = now ( ) ;
357
363
358
- let rate = PublishRateLimit {
364
+ let rate = RateLimiter {
359
365
rate : Duration :: from_secs ( 1 ) ,
360
366
burst : 10 ,
361
367
} ;
0 commit comments