@@ -14,7 +14,7 @@ use cargo_util::paths;
14
14
use curl:: easy:: { HttpVersion , List } ;
15
15
use curl:: multi:: { EasyHandle , Multi } ;
16
16
use log:: { debug, trace} ;
17
- use std:: cell:: { Cell , RefCell } ;
17
+ use std:: cell:: RefCell ;
18
18
use std:: collections:: { HashMap , HashSet } ;
19
19
use std:: fs:: { self , File } ;
20
20
use std:: path:: { Path , PathBuf } ;
@@ -98,6 +98,9 @@ pub struct Downloads<'cfg> {
98
98
progress : RefCell < Option < Progress < ' cfg > > > ,
99
99
/// Number of downloads that have successfully finished.
100
100
downloads_finished : usize ,
101
+ /// Number of times the caller has requested blocking. This is used for
102
+ /// an estimate of progress.
103
+ blocking_calls : usize ,
101
104
}
102
105
103
106
struct Download {
@@ -113,10 +116,6 @@ struct Download {
113
116
114
117
/// ETag or Last-Modified header received from the server (if any).
115
118
index_version : RefCell < Option < String > > ,
116
-
117
- /// Statistics updated from the progress callback in libcurl.
118
- total : Cell < u64 > ,
119
- current : Cell < u64 > ,
120
119
}
121
120
122
121
struct CompletedDownload {
@@ -159,10 +158,11 @@ impl<'cfg> HttpRegistry<'cfg> {
159
158
results : HashMap :: new ( ) ,
160
159
progress : RefCell :: new ( Some ( Progress :: with_style (
161
160
"Fetch" ,
162
- ProgressStyle :: Ratio ,
161
+ ProgressStyle :: Indeterminate ,
163
162
config,
164
163
) ) ) ,
165
164
downloads_finished : 0 ,
165
+ blocking_calls : 0 ,
166
166
} ,
167
167
fresh : HashSet :: new ( ) ,
168
168
requested_update : false ,
@@ -457,15 +457,6 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
457
457
Ok ( buf. len ( ) )
458
458
} ) ?;
459
459
460
- // Same goes for the progress function -- it goes through thread-local storage.
461
- handle. progress ( true ) ?;
462
- handle. progress_function ( move |dl_total, dl_cur, _, _| {
463
- tls:: with ( |downloads| match downloads {
464
- Some ( d) => d. progress ( token, dl_total as u64 , dl_cur as u64 ) ,
465
- None => false ,
466
- } )
467
- } ) ?;
468
-
469
460
// And ditto for the header function.
470
461
handle. header_function ( move |buf| {
471
462
if let Some ( ( tag, value) ) = Self :: handle_http_header ( buf) {
@@ -494,8 +485,6 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
494
485
data : RefCell :: new ( Vec :: new ( ) ) ,
495
486
path : path. to_path_buf ( ) ,
496
487
index_version : RefCell :: new ( None ) ,
497
- total : Cell :: new ( 0 ) ,
498
- current : Cell :: new ( 0 ) ,
499
488
} ;
500
489
501
490
// Finally add the request we've lined up to the pool of requests that cURL manages.
@@ -588,11 +577,11 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
588
577
}
589
578
590
579
fn block_until_ready ( & mut self ) -> CargoResult < ( ) > {
591
- let initial_pending_count = self . downloads . pending . len ( ) ;
592
580
trace ! (
593
581
"block_until_ready: {} transfers pending" ,
594
- initial_pending_count
582
+ self . downloads . pending . len ( )
595
583
) ;
584
+ self . downloads . blocking_calls += 1 ;
596
585
597
586
loop {
598
587
self . handle_completed_downloads ( ) ?;
@@ -622,21 +611,31 @@ impl<'cfg> RegistryData for HttpRegistry<'cfg> {
622
611
}
623
612
624
613
impl < ' cfg > Downloads < ' cfg > {
625
- fn progress ( & self , token : usize , total : u64 , cur : u64 ) -> bool {
626
- let dl = & self . pending [ & token] . 0 ;
627
- dl. total . set ( total) ;
628
- dl. current . set ( cur) ;
629
- true
630
- }
631
-
632
614
fn tick ( & self ) -> CargoResult < ( ) > {
633
615
let mut progress = self . progress . borrow_mut ( ) ;
634
616
let progress = progress. as_mut ( ) . unwrap ( ) ;
635
617
618
+ // Since the sparse protocol discovers dependencies as it goes,
619
+ // it's not possible to get an accurate progress indication.
620
+ //
621
+ // As an approximation, we assume that the depth of the dependency graph
622
+ // is fixed, and base the progress on how many times the caller has asked
623
+ // for blocking. If there are actually additional dependencies, the progress
624
+ // bar will get stuck. If there are fewer dependencies, it will disappear
625
+ // early. It will never go backwards.
626
+ //
627
+ // The status text also contains the number of completed & pending requests, which
628
+ // gives an better indication of forward progress.
629
+ let approximate_tree_depth = 10 ;
630
+
636
631
progress. tick (
637
- self . downloads_finished ,
638
- self . downloads_finished + self . pending . len ( ) ,
639
- "" ,
632
+ self . blocking_calls . min ( approximate_tree_depth) ,
633
+ approximate_tree_depth + 1 ,
634
+ & format ! (
635
+ " {} complete; {} pending" ,
636
+ self . downloads_finished,
637
+ self . pending. len( )
638
+ ) ,
640
639
)
641
640
}
642
641
}
0 commit comments