@@ -13,7 +13,7 @@ use std::fmt;
13
13
use std:: fs:: { self , File } ;
14
14
use std:: io:: { BufRead , BufReader , Read , Write } ;
15
15
use std:: net:: { SocketAddr , TcpListener , TcpStream } ;
16
- use std:: path:: PathBuf ;
16
+ use std:: path:: { Path , PathBuf } ;
17
17
use std:: thread:: { self , JoinHandle } ;
18
18
use tar:: { Builder , Header } ;
19
19
use time:: format_description:: well_known:: Rfc3339 ;
@@ -98,6 +98,8 @@ pub struct RegistryBuilder {
98
98
configure_registry : bool ,
99
99
/// API responders.
100
100
custom_responders : HashMap < & ' static str , Box < dyn Send + Fn ( & Request , & HttpServer ) -> Response > > ,
101
+ /// If nonzero, the git index update to be delayed by the given number of seconds.
102
+ delayed_index_update : usize ,
101
103
}
102
104
103
105
pub struct TestRegistry {
@@ -157,6 +159,7 @@ impl RegistryBuilder {
157
159
configure_registry : true ,
158
160
configure_token : true ,
159
161
custom_responders : HashMap :: new ( ) ,
162
+ delayed_index_update : 0 ,
160
163
}
161
164
}
162
165
@@ -171,6 +174,13 @@ impl RegistryBuilder {
171
174
self
172
175
}
173
176
177
+ /// Configures the git index update to be delayed by the given number of seconds.
178
+ #[ must_use]
179
+ pub fn delayed_index_update ( mut self , delay : usize ) -> Self {
180
+ self . delayed_index_update = delay;
181
+ self
182
+ }
183
+
174
184
/// Sets whether or not to initialize as an alternative registry.
175
185
#[ must_use]
176
186
pub fn alternative_named ( mut self , alt : & str ) -> Self {
@@ -265,6 +275,7 @@ impl RegistryBuilder {
265
275
token. clone ( ) ,
266
276
self . auth_required ,
267
277
self . custom_responders ,
278
+ self . delayed_index_update ,
268
279
) ;
269
280
let index_url = if self . http_index {
270
281
server. index_url ( )
@@ -591,6 +602,7 @@ pub struct HttpServer {
591
602
token : Token ,
592
603
auth_required : bool ,
593
604
custom_responders : HashMap < & ' static str , Box < dyn Send + Fn ( & Request , & HttpServer ) -> Response > > ,
605
+ delayed_index_update : usize ,
594
606
}
595
607
596
608
/// A helper struct that collects the arguments for [HttpServer::check_authorized].
@@ -613,6 +625,7 @@ impl HttpServer {
613
625
& ' static str ,
614
626
Box < dyn Send + Fn ( & Request , & HttpServer ) -> Response > ,
615
627
> ,
628
+ delayed_index_update : usize ,
616
629
) -> HttpServerHandle {
617
630
let listener = TcpListener :: bind ( "127.0.0.1:0" ) . unwrap ( ) ;
618
631
let addr = listener. local_addr ( ) . unwrap ( ) ;
@@ -625,6 +638,7 @@ impl HttpServer {
625
638
token,
626
639
auth_required,
627
640
custom_responders : api_responders,
641
+ delayed_index_update,
628
642
} ;
629
643
let handle = Some ( thread:: spawn ( move || server. start ( ) ) ) ;
630
644
HttpServerHandle { addr, handle }
@@ -1040,49 +1054,23 @@ impl HttpServer {
1040
1054
return self . unauthorized ( req) ;
1041
1055
}
1042
1056
1043
- // Write the `.crate`
1044
1057
let dst = self
1045
1058
. dl_path
1046
1059
. join ( & new_crate. name )
1047
1060
. join ( & new_crate. vers )
1048
1061
. join ( "download" ) ;
1049
- t ! ( fs:: create_dir_all( dst. parent( ) . unwrap( ) ) ) ;
1050
- t ! ( fs:: write( & dst, file) ) ;
1051
-
1052
- let deps = new_crate
1053
- . deps
1054
- . iter ( )
1055
- . map ( |dep| {
1056
- let ( name, package) = match & dep. explicit_name_in_toml {
1057
- Some ( explicit) => ( explicit. to_string ( ) , Some ( dep. name . to_string ( ) ) ) ,
1058
- None => ( dep. name . to_string ( ) , None ) ,
1059
- } ;
1060
- serde_json:: json!( {
1061
- "name" : name,
1062
- "req" : dep. version_req,
1063
- "features" : dep. features,
1064
- "default_features" : true ,
1065
- "target" : dep. target,
1066
- "optional" : dep. optional,
1067
- "kind" : dep. kind,
1068
- "registry" : dep. registry,
1069
- "package" : package,
1070
- } )
1071
- } )
1072
- . collect :: < Vec < _ > > ( ) ;
1073
-
1074
- let line = create_index_line (
1075
- serde_json:: json!( new_crate. name) ,
1076
- & new_crate. vers ,
1077
- deps,
1078
- & file_cksum,
1079
- new_crate. features ,
1080
- false ,
1081
- new_crate. links ,
1082
- None ,
1083
- ) ;
1084
1062
1085
- write_to_index ( & self . registry_path , & new_crate. name , line, false ) ;
1063
+ if self . delayed_index_update == 0 {
1064
+ save_new_crate ( dst, new_crate, file, file_cksum, & self . registry_path ) ;
1065
+ } else {
1066
+ let delayed_index_update = self . delayed_index_update ;
1067
+ let registry_path = self . registry_path . clone ( ) ;
1068
+ let file = Vec :: from ( file) ;
1069
+ thread:: spawn ( move || {
1070
+ thread:: sleep ( std:: time:: Duration :: new ( delayed_index_update as u64 , 0 ) ) ;
1071
+ save_new_crate ( dst, new_crate, & file, file_cksum, & registry_path) ;
1072
+ } ) ;
1073
+ }
1086
1074
1087
1075
self . ok ( & req)
1088
1076
} else {
@@ -1095,6 +1083,53 @@ impl HttpServer {
1095
1083
}
1096
1084
}
1097
1085
1086
+ fn save_new_crate (
1087
+ dst : PathBuf ,
1088
+ new_crate : crates_io:: NewCrate ,
1089
+ file : & [ u8 ] ,
1090
+ file_cksum : String ,
1091
+ registry_path : & Path ,
1092
+ ) {
1093
+ // Write the `.crate`
1094
+ t ! ( fs:: create_dir_all( dst. parent( ) . unwrap( ) ) ) ;
1095
+ t ! ( fs:: write( & dst, file) ) ;
1096
+
1097
+ let deps = new_crate
1098
+ . deps
1099
+ . iter ( )
1100
+ . map ( |dep| {
1101
+ let ( name, package) = match & dep. explicit_name_in_toml {
1102
+ Some ( explicit) => ( explicit. to_string ( ) , Some ( dep. name . to_string ( ) ) ) ,
1103
+ None => ( dep. name . to_string ( ) , None ) ,
1104
+ } ;
1105
+ serde_json:: json!( {
1106
+ "name" : name,
1107
+ "req" : dep. version_req,
1108
+ "features" : dep. features,
1109
+ "default_features" : true ,
1110
+ "target" : dep. target,
1111
+ "optional" : dep. optional,
1112
+ "kind" : dep. kind,
1113
+ "registry" : dep. registry,
1114
+ "package" : package,
1115
+ } )
1116
+ } )
1117
+ . collect :: < Vec < _ > > ( ) ;
1118
+
1119
+ let line = create_index_line (
1120
+ serde_json:: json!( new_crate. name) ,
1121
+ & new_crate. vers ,
1122
+ deps,
1123
+ & file_cksum,
1124
+ new_crate. features ,
1125
+ false ,
1126
+ new_crate. links ,
1127
+ None ,
1128
+ ) ;
1129
+
1130
+ write_to_index ( registry_path, & new_crate. name , line, false ) ;
1131
+ }
1132
+
1098
1133
impl Package {
1099
1134
/// Creates a new package builder.
1100
1135
/// Call `publish()` to finalize and build the package.
0 commit comments