1
- use super :: { download_thread, DownloadHandle , DownloadRequest } ;
1
+ use super :: { config :: DownloadManagerConfig , download_thread, DownloadHandle , DownloadRequest } ;
2
2
use crate :: { error:: DownloadError , Error } ;
3
3
use reqwest:: { Client , Url } ;
4
4
use std:: { path:: Path , sync:: Arc } ;
5
5
use tokio:: sync:: { mpsc, Semaphore } ;
6
6
use tokio_util:: sync:: CancellationToken ;
7
7
8
- const QUEUE_SIZE : usize = 100 ;
9
-
10
8
#[ derive( Debug ) ]
11
9
pub struct DownloadManager {
12
10
queue : mpsc:: Sender < DownloadRequest > ,
13
11
semaphore : Arc < Semaphore > ,
14
12
cancel : CancellationToken ,
13
+ config : DownloadManagerConfig ,
15
14
}
16
15
17
16
impl Drop for DownloadManager {
@@ -21,15 +20,22 @@ impl Drop for DownloadManager {
21
20
}
22
21
}
23
22
23
+ impl Default for DownloadManager {
24
+ fn default ( ) -> Self {
25
+ Self :: with_config ( DownloadManagerConfig :: default ( ) )
26
+ }
27
+ }
28
+
24
29
impl DownloadManager {
25
- pub fn new ( limit : usize ) -> Self {
26
- let ( tx, rx) = mpsc:: channel ( QUEUE_SIZE ) ;
30
+ pub fn with_config ( config : DownloadManagerConfig ) -> Self {
31
+ let ( tx, rx) = mpsc:: channel ( config . queue_size ( ) ) ;
27
32
let client = Client :: new ( ) ;
28
- let semaphore = Arc :: new ( Semaphore :: new ( limit ) ) ;
33
+ let semaphore = Arc :: new ( Semaphore :: new ( config . max_concurrent ( ) ) ) ;
29
34
let manager = Self {
30
35
queue : tx,
31
36
semaphore : semaphore. clone ( ) ,
32
37
cancel : CancellationToken :: new ( ) ,
38
+ config,
33
39
} ;
34
40
// Spawn the dispatcher thread to handle download requests
35
41
tokio:: spawn ( async move { dispatcher_thread ( client, rx, semaphore) . await } ) ;
@@ -63,16 +69,24 @@ impl DownloadManager {
63
69
Ok ( handle)
64
70
}
65
71
66
- pub fn set_max_parallel_downloads ( & self , limit : usize ) {
67
- let current = self . semaphore . available_permits ( ) ;
72
+ pub async fn set_max_parallel_downloads ( & self , limit : usize ) -> Result < ( ) , Error > {
73
+ let current = self . config . max_concurrent ( ) ;
68
74
if limit > current {
69
75
self . semaphore . add_permits ( limit - current) ;
70
76
} else if limit < current {
71
77
let to_remove = current - limit;
72
- for _ in 0 ..to_remove {
73
- let _ = self . semaphore . try_acquire ( ) ;
74
- }
78
+
79
+ let permits = self
80
+ . semaphore
81
+ . acquire_many ( to_remove as u32 )
82
+ . await
83
+ . map_err ( |_| Error :: Download ( DownloadError :: ManagerShutdown ) ) ?;
84
+
85
+ permits. forget ( ) ;
75
86
}
87
+ self . config . set_max_concurrent ( limit) ;
88
+
89
+ Ok ( ( ) )
76
90
}
77
91
78
92
pub fn cancel_all ( & self ) {
0 commit comments