Parameterize RunnerProtoError over ShutdownProvider

Instead of being generic over `S: Error + 'static`, the
`RunnerProtoError` type is now generic over `S: ShutdownProvider` and we
can use `S::Error` inside its definition, instead of instantiating it
from the `RunnerProto<S>` with `S::Error` directly.

This is a little cleaner and more readable, but does have a side effect
that requires `ShutdownProvider: Debug`.

This is in preparation for adding another generic parameter to
`RunnerProtoError`, making it generic over errors from the
`PerfProvider`. Without this change, it would require being generic over
both of the `PerfProvider`'s error types (`PerfProvider::DiskIoError`
and `PerfProvider::CpuTimeError`), making the types longer and messier.
This commit is contained in:
Barret Rennie 2020-06-17 17:25:11 -04:00
Родитель ad51b08f31
Коммит e3f6b27753
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4D71D86C09132D72
3 изменённых файлов: 34 добавлений и 40 удалений

Просмотреть файл

@ -20,7 +20,7 @@ pub use error::WindowsError;
pub use perf::IoCounters;
/// A trait providing the ability to restart the current machine.
pub trait ShutdownProvider {
pub trait ShutdownProvider: Debug {
/// The error
type Error: Error + 'static;
@ -50,7 +50,7 @@ pub trait PerfProvider: Debug {
}
/// A [`ShutdownProvider`](trait.ShutdownProvider.html) that uses the Windows API.
#[derive(Default)]
#[derive(Debug, Default)]
pub struct WindowsShutdownProvider {
/// Whether or not to skip the actual restart.
#[cfg(debug_assertions)]

Просмотреть файл

@ -69,7 +69,7 @@ where
}
/// Handshake with FxRecorder.
pub async fn handshake_reply(&mut self) -> Result<bool, RunnerProtoError<S::Error>> {
pub async fn handshake_reply(&mut self) -> Result<bool, RunnerProtoError<S>> {
info!(self.log, "Handshaking ...");
let Handshake { restart } = self.recv().await?;
@ -98,7 +98,7 @@ where
pub async fn download_build_reply(
&mut self,
download_dir: &Path,
) -> Result<PathBuf, RunnerProtoError<S::Error>> {
) -> Result<PathBuf, RunnerProtoError<S>> {
let DownloadBuild { task_id } = self.recv().await?;
info!(self.log, "Received build download request"; "task_id" => &task_id);
@ -169,8 +169,9 @@ where
pub async fn send_profile_reply(
&mut self,
download_dir: &Path,
) -> Result<Option<PathBuf>, RunnerProtoError<S::Error>> {
) -> Result<Option<PathBuf>, RunnerProtoError<S>> {
info!(self.log, "Waiting for profile...");
let SendProfile { profile_size } = self.recv().await?;
let profile_size = match profile_size {
@ -272,7 +273,7 @@ where
stream: &mut TcpStream,
download_dir: &Path,
profile_size: u64,
) -> Result<PathBuf, RunnerProtoError<S::Error>> {
) -> Result<PathBuf, RunnerProtoError<S>> {
let zip_path = download_dir.join("profile.zip");
let mut f = File::create(&zip_path).await?;
@ -281,10 +282,7 @@ where
Ok(zip_path)
}
pub async fn send_prefs_reply(
&mut self,
prefs_path: &Path,
) -> Result<(), RunnerProtoError<S::Error>> {
pub async fn send_prefs_reply(&mut self, prefs_path: &Path) -> Result<(), RunnerProtoError<S>> {
let SendPrefs { prefs } = self.recv().await?;
if prefs.is_empty() {
@ -327,10 +325,10 @@ where
}
#[derive(Debug, Display)]
pub enum RunnerProtoError<S> {
pub enum RunnerProtoError<S: ShutdownProvider> {
Proto(ProtoError<RecorderMessageKind>),
Shutdown(S),
Shutdown(S::Error),
Taskcluster(TaskclusterError),
@ -345,7 +343,7 @@ pub enum RunnerProtoError<S> {
impl<S> Error for RunnerProtoError<S>
where
S: Error + 'static,
S: ShutdownProvider,
{
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
@ -361,7 +359,7 @@ where
impl<S> From<ProtoError<RecorderMessageKind>> for RunnerProtoError<S>
where
S: Error + 'static,
S: ShutdownProvider,
{
fn from(e: ProtoError<RecorderMessageKind>) -> Self {
RunnerProtoError::Proto(e)
@ -370,7 +368,7 @@ where
impl<S> From<TaskclusterError> for RunnerProtoError<S>
where
S: Error + 'static,
S: ShutdownProvider,
{
fn from(e: TaskclusterError) -> Self {
RunnerProtoError::Taskcluster(e)
@ -378,7 +376,7 @@ where
}
impl<S> From<ZipError> for RunnerProtoError<S>
where
S: Error + 'static,
S: ShutdownProvider,
{
fn from(e: ZipError) -> Self {
RunnerProtoError::Zip(e)
@ -387,7 +385,7 @@ where
impl<S> From<io::Error> for RunnerProtoError<S>
where
S: Error + 'static,
S: ShutdownProvider,
{
fn from(e: io::Error) -> Self {
RunnerProtoError::Proto(ProtoError::Io(e))

Просмотреть файл

@ -24,7 +24,7 @@ use tokio::net::{TcpListener, TcpStream};
use tokio::prelude::*;
use url::Url;
#[derive(Default)]
#[derive(Debug, Default)]
pub struct TestShutdownProvider {
error: Option<&'static str>,
}
@ -301,29 +301,25 @@ async fn test_download_build() {
run_proto_test(
&mut listener,
TestShutdownProvider::default(),
|mut runner| {
async move {
assert_matches!(
runner
.download_build_reply(download_dir.path())
.await
.unwrap_err(),
RunnerProtoError::MissingFirefox
);
}
|mut runner| async move {
assert_matches!(
runner
.download_build_reply(download_dir.path())
.await
.unwrap_err(),
RunnerProtoError::MissingFirefox
);
},
|mut recorder| {
async move {
assert_matches!(
recorder.download_build("foo").await.unwrap_err(),
RecorderProtoError::Proto(ProtoError::Foreign(e)) => {
assert_eq!(
e.to_string(),
RunnerProtoError::<<TestShutdownProvider as ShutdownProvider>::Error>::MissingFirefox.to_string()
);
}
);
}
|mut recorder| async move {
assert_matches!(
recorder.download_build("foo").await.unwrap_err(),
RecorderProtoError::Proto(ProtoError::Foreign(e)) => {
assert_eq!(
e.to_string(),
RunnerProtoError::<TestShutdownProvider>::MissingFirefox.to_string()
);
}
);
},
)
.await;