blob: 55122117ece42772e450787f0f1e7384d0213e97 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
//! ref: composer/src/Composer/Util/Loop.php
use crate::util::HttpDownloader;
use crate::util::ProcessExecutor;
use anyhow::Result;
use shirabe_external_packages::symfony::component::console::helper::ProgressBar;
#[derive(Debug)]
pub struct Loop {
http_downloader: std::rc::Rc<std::cell::RefCell<HttpDownloader>>,
process_executor: Option<std::rc::Rc<std::cell::RefCell<ProcessExecutor>>>,
}
impl Loop {
pub fn new(
http_downloader: std::rc::Rc<std::cell::RefCell<HttpDownloader>>,
process_executor: Option<std::rc::Rc<std::cell::RefCell<ProcessExecutor>>>,
) -> Self {
http_downloader.borrow_mut().enable_async();
let process_executor = process_executor.map(|pe| {
pe.borrow_mut().enable_async();
pe
});
Self {
http_downloader,
process_executor,
}
}
pub fn get_http_downloader(&self) -> &std::rc::Rc<std::cell::RefCell<HttpDownloader>> {
&self.http_downloader
}
pub fn get_process_executor(
&self,
) -> Option<&std::rc::Rc<std::cell::RefCell<ProcessExecutor>>> {
self.process_executor.as_ref()
}
pub async fn wait<'p>(
&mut self,
promises: Vec<std::pin::Pin<Box<dyn std::future::Future<Output = Result<()>> + 'p>>>,
_progress: Option<&mut ProgressBar>,
) -> Result<()> {
let mut uncaught: Option<anyhow::Error> = None;
// TODO(phase-c-promise): the asynchronous worker classes (HttpDownloader / ProcessExecutor)
// run single-threaded for now, so the promises are consumed serially. Once the workers run
// on a multi-thread runtime these futures should be driven concurrently instead of in order.
// The PHP progress bar is tied to the worker active-job count and is also deferred until then.
for promise in promises {
if let Err(e) = promise.await {
if uncaught.is_none() {
uncaught = Some(e);
}
}
}
if let Some(e) = uncaught {
return Err(e);
}
Ok(())
}
pub fn abort_jobs(&self) {
// TODO(phase-c-promise): no-op until a cancellation mechanism is introduced. PHP cancels
// every in-flight promise group it tracks in $currentPromises; reintroduce that tracking
// once the asynchronous workers support cancellation on a multi-thread runtime.
}
}
|