@@ -83,7 +83,8 @@ impl BuildQueue {
8383 ON CONFLICT (name, version) DO UPDATE
8484 SET priority = EXCLUDED.priority,
8585 registry = EXCLUDED.registry,
86- attempt = 0
86+ attempt = 0,
87+ last_attempt = NULL
8788 ;" ,
8889 & [ & name, & version, & priority, & registry] ,
8990 ) ?;
@@ -179,11 +180,16 @@ impl BuildQueue {
179180 . query_opt (
180181 "SELECT id, name, version, priority, registry
181182 FROM queue
182- WHERE attempt < $1
183+ WHERE
184+ attempt < $1 AND
185+ (last_attempt IS NULL OR last_attempt < NOW() - make_interval(secs => $2))
183186 ORDER BY priority ASC, attempt ASC, id ASC
184187 LIMIT 1
185188 FOR UPDATE SKIP LOCKED" ,
186- & [ & self . max_attempts ] ,
189+ & [
190+ & self . max_attempts ,
191+ & self . config . delay_between_build_attempts . as_secs_f64 ( ) ,
192+ ] ,
187193 ) ?
188194 . map ( |row| QueuedCrate {
189195 id : row. get ( "id" ) ,
@@ -219,7 +225,12 @@ impl BuildQueue {
219225 // Increase attempt count
220226 let attempt: i32 = transaction
221227 . query_one (
222- "UPDATE queue SET attempt = attempt + 1 WHERE id = $1 RETURNING attempt;" ,
228+ "UPDATE queue
229+ SET
230+ attempt = attempt + 1,
231+ last_attempt = NOW()
232+ WHERE id = $1
233+ RETURNING attempt;" ,
223234 & [ & to_process. id ] ,
224235 ) ?
225236 . get ( 0 ) ;
@@ -502,6 +513,8 @@ impl BuildQueue {
502513#[ cfg( test) ]
503514mod tests {
504515 use super :: * ;
516+ use chrono:: { DateTime , Utc } ;
517+ use std:: time:: Duration ;
505518
506519 #[ test]
507520 fn test_add_duplicate_doesnt_fail_last_priority_wins ( ) {
@@ -531,8 +544,8 @@ mod tests {
531544 let mut conn = env. db ( ) . conn ( ) ;
532545 conn. execute (
533546 "
534- INSERT INTO queue (name, version, priority, attempt )
535- VALUES ('failed_crate', '0.1.1', 0, 99)" ,
547+ INSERT INTO queue (name, version, priority, attempt, last_attempt )
548+ VALUES ('failed_crate', '0.1.1', 0, 99, NOW() )" ,
536549 & [ ] ,
537550 ) ?;
538551
@@ -544,14 +557,15 @@ mod tests {
544557
545558 let row = conn
546559 . query_opt (
547- "SELECT priority, attempt
560+ "SELECT priority, attempt, last_attempt
548561 FROM queue
549562 WHERE name = $1 AND version = $2" ,
550563 & [ & "failed_crate" , & "0.1.1" ] ,
551564 ) ?
552565 . unwrap ( ) ;
553566 assert_eq ! ( row. get:: <_, i32 >( 0 ) , 9 ) ;
554567 assert_eq ! ( row. get:: <_, i32 >( 1 ) , 0 ) ;
568+ assert ! ( row. get:: <_, Option <DateTime <Utc >>>( 2 ) . is_none( ) ) ;
555569 Ok ( ( ) )
556570 } )
557571 }
@@ -574,13 +588,60 @@ mod tests {
574588 } )
575589 }
576590
591+ #[ test]
592+ fn test_wait_between_build_attempts ( ) {
593+ crate :: test:: wrapper ( |env| {
594+ env. override_config ( |config| {
595+ config. build_attempts = 99 ;
596+ config. delay_between_build_attempts = Duration :: from_secs ( 1 ) ;
597+ } ) ;
598+
599+ let queue = env. build_queue ( ) ;
600+
601+ queue. add_crate ( "krate" , "1.0.0" , 0 , None ) ?;
602+
603+ // first let it fail
604+ queue. process_next_crate ( |krate| {
605+ assert_eq ! ( krate. name, "krate" ) ;
606+ anyhow:: bail!( "simulate a failure" ) ;
607+ } ) ?;
608+
609+ queue. process_next_crate ( |_| {
610+ // this can't happen since we didn't wait between attempts
611+ unreachable ! ( ) ;
612+ } ) ?;
613+
614+ {
615+ // fake the build-attempt timestamp so it's older
616+ let mut conn = env. db ( ) . conn ( ) ;
617+ conn. execute (
618+ "UPDATE queue SET last_attempt = $1" ,
619+ & [ & ( Utc :: now ( ) - chrono:: Duration :: seconds ( 60 ) ) ] ,
620+ ) ?;
621+ }
622+
623+ let mut handled = false ;
624+ // now we can process it again
625+ queue. process_next_crate ( |krate| {
626+ assert_eq ! ( krate. name, "krate" ) ;
627+ handled = true ;
628+ Ok ( ( ) )
629+ } ) ?;
630+
631+ assert ! ( handled) ;
632+
633+ Ok ( ( ) )
634+ } )
635+ }
636+
577637 #[ test]
578638 fn test_add_and_process_crates ( ) {
579639 const MAX_ATTEMPTS : u16 = 3 ;
580640
581641 crate :: test:: wrapper ( |env| {
582642 env. override_config ( |config| {
583643 config. build_attempts = MAX_ATTEMPTS ;
644+ config. delay_between_build_attempts = Duration :: ZERO ;
584645 } ) ;
585646
586647 let queue = env. build_queue ( ) ;
@@ -775,6 +836,7 @@ mod tests {
775836 crate :: test:: wrapper ( |env| {
776837 env. override_config ( |config| {
777838 config. build_attempts = MAX_ATTEMPTS ;
839+ config. delay_between_build_attempts = Duration :: ZERO ;
778840 } ) ;
779841 let queue = env. build_queue ( ) ;
780842
0 commit comments