File tree Expand file tree Collapse file tree 6 files changed +10624
-1
lines changed Expand file tree Collapse file tree 6 files changed +10624
-1
lines changed Original file line number Diff line number Diff line change @@ -10,9 +10,11 @@ protobuf-src = ["types/protobuf-src"]
1010chirp = [" types" ]
1111
1212[dependencies ]
13+ async-trait = " 0.1"
1314formatted-error = { path = " ../formatted-error" }
1415types = { path = " ../types/core" , optional = true }
1516http = " 0.2"
17+ reqwest = " 0.11"
1618serde = { version = " 1.0" , features = [" derive" ] }
1719serde_json = " 1.0"
1820thiserror = " 1.0"
Original file line number Diff line number Diff line change 1- use crate :: Location ;
1+ use crate :: { bail, GlobalResult , Location } ;
2+ use async_trait:: async_trait;
23
34#[ derive( Debug , thiserror:: Error ) ]
45pub enum AssertionError {
@@ -122,3 +123,23 @@ impl<'a, T> UnwrapOrAssertError for &'a &'a Option<T> {
122123 }
123124 }
124125}
126+
127+ #[ async_trait]
128+ pub trait ToGlobalError : Sized {
129+ async fn to_global_error ( self ) -> GlobalResult < Self > ;
130+ }
131+
132+ #[ async_trait]
133+ impl ToGlobalError for reqwest:: Response {
134+ async fn to_global_error ( self ) -> GlobalResult < Self > {
135+ if self . status ( ) . is_success ( ) {
136+ Ok ( self )
137+ } else {
138+ let url = self . url ( ) . clone ( ) ;
139+ let status = self . status ( ) ;
140+ let body = self . text ( ) . await ?;
141+
142+ bail ! ( format!( "{url} ({status}):\n {body}" ) ) ;
143+ }
144+ }
145+ }
Original file line number Diff line number Diff line change @@ -11,6 +11,7 @@ macros = []
1111serde = []
1212
1313[dependencies ]
14+ async-trait = " 0.1"
1415bcrypt = " 0.13.0"
1516chrono = " 0.4"
1617formatted-error = { path = " ../../formatted-error" , optional = true }
@@ -20,6 +21,7 @@ ipnet = { version = "2.7", features = ["serde"] }
2021lazy_static = " 1.4"
2122rand = " 0.8"
2223regex = " 1.4"
24+ reqwest = " 0.11"
2325rivet-util-env = { path = " ../env" }
2426rivet-util-macros = { path = " ../macros" }
2527serde = { version = " 1.0" , features = [" derive" ] }
Original file line number Diff line number Diff line change @@ -16,6 +16,7 @@ pub mod geo;
1616pub mod glob;
1717pub mod math;
1818pub mod net;
19+ pub mod req;
1920pub mod route;
2021pub mod sort;
2122pub mod timestamp;
Original file line number Diff line number Diff line change 1+ use std:: time:: Duration ;
2+
3+ use async_trait:: async_trait;
4+ use global_error:: prelude:: * ;
5+
6+ #[ async_trait]
7+ pub trait SendRetry {
8+ /// Retries the request upon receiving a 429 response.
9+ async fn send_retry ( self , mut retries : usize ) -> GlobalResult < reqwest:: Response > ;
10+ }
11+
12+ #[ async_trait]
13+ impl SendRetry for reqwest:: RequestBuilder {
14+ async fn send_retry ( self , mut retries : usize ) -> GlobalResult < reqwest:: Response > {
15+ loop {
16+ let req = unwrap ! ( self . try_clone( ) ) ;
17+ let res = req. send ( ) . await ?;
18+
19+ if let reqwest:: StatusCode :: TOO_MANY_REQUESTS = res. status ( ) {
20+ if retries != 0 {
21+ retries -= 1 ;
22+
23+ // TODO: Parse all valid Retry-After formats. Currently only parses duration
24+ let retry_time = res
25+ . headers ( )
26+ . get ( "Retry-After" )
27+ . map ( |x| x. to_str ( ) )
28+ . transpose ( ) ?
29+ . map ( |x| x. parse :: < u64 > ( ) )
30+ . transpose ( ) ?
31+ . unwrap_or ( 5 ) ;
32+ tokio:: time:: sleep ( Duration :: from_secs ( retry_time) ) . await ;
33+
34+ continue ;
35+ }
36+ }
37+
38+ break Ok ( res) ;
39+ }
40+ }
41+ }
You can’t perform that action at this time.
0 commit comments