Move artifacts states into memory in PVF validation host (#3907)

* pvf host: store only compiled artifacts on disk

* Correctly handle failed artifacts

* Serialize result of PVF preparation uniquely

* Set the artifact state depending on the result

* Return the result of PVF preparation directly

* Move PrepareError to the error module

* Update doc comments

* Update misleading comment

* Cleanup docs

* Conclude a test job with an error

Co-authored-by: Sergei Shulepov <sergei@parity.io>
This commit is contained in:
Chris Sosnin
2021-10-22 19:37:58 +03:00
committed by GitHub
parent ad33b8749b
commit 182667830f
7 changed files with 200 additions and 137 deletions
+28 -9
View File
@@ -344,8 +344,7 @@ async fn run(
.await);
},
from_prepare_queue = from_prepare_queue_rx.next() => {
let prepare::FromQueue::Prepared(artifact_id)
= break_if_fatal!(from_prepare_queue.ok_or(Fatal));
let from_queue = break_if_fatal!(from_prepare_queue.ok_or(Fatal));
// Note that preparation always succeeds.
//
@@ -361,7 +360,7 @@ async fn run(
&mut artifacts,
&mut to_execute_queue_tx,
&mut awaiting_prepare,
artifact_id,
from_queue,
).await);
},
}
@@ -439,6 +438,9 @@ async fn handle_execute_pvf(
awaiting_prepare.add(artifact_id, execution_timeout, params, result_tx);
},
ArtifactState::FailedToProcess(error) => {
let _ = result_tx.send(Err(ValidationError::from(error.clone())));
},
}
} else {
// Artifact is unknown: register it and enqueue a job with the corresponding priority and
@@ -470,6 +472,7 @@ async fn handle_heads_up(
// Already preparing. We don't need to send a priority amend either because
// it can't get any lower than the background.
},
ArtifactState::FailedToProcess(_) => {},
}
} else {
// The artifact is unknown: register it and put a background job into the prepare queue.
@@ -491,8 +494,10 @@ async fn handle_prepare_done(
artifacts: &mut Artifacts,
execute_queue: &mut mpsc::Sender<execute::ToQueue>,
awaiting_prepare: &mut AwaitingPrepare,
artifact_id: ArtifactId,
from_queue: prepare::FromQueue,
) -> Result<(), Fatal> {
let prepare::FromQueue { artifact_id, result } = from_queue;
// Make some sanity checks and extract the current state.
let state = match artifacts.artifact_state_mut(&artifact_id) {
None => {
@@ -513,6 +518,12 @@ async fn handle_prepare_done(
never!("the artifact is already prepared: {:?}", artifact_id);
return Ok(())
},
Some(ArtifactState::FailedToProcess(_)) => {
// The reasoning is similar to the above, the artifact cannot be
// processed at this point.
never!("the artifact is already processed unsuccessfully: {:?}", artifact_id);
return Ok(())
},
Some(state @ ArtifactState::Preparing) => state,
};
@@ -526,6 +537,12 @@ async fn handle_prepare_done(
continue
}
// Don't send failed artifacts to the execution's queue.
if let Err(ref error) = result {
let _ = result_tx.send(Err(ValidationError::from(error.clone())));
continue
}
send_execute(
execute_queue,
execute::ToQueue::Enqueue {
@@ -538,8 +555,10 @@ async fn handle_prepare_done(
.await?;
}
// Now consider the artifact prepared.
*state = ArtifactState::Prepared { last_time_needed: SystemTime::now() };
*state = match result {
Ok(()) => ArtifactState::Prepared { last_time_needed: SystemTime::now() },
Err(error) => ArtifactState::FailedToProcess(error.clone()),
};
Ok(())
}
@@ -937,7 +956,7 @@ mod tests {
);
test.from_prepare_queue_tx
.send(prepare::FromQueue::Prepared(artifact_id(1)))
.send(prepare::FromQueue { artifact_id: artifact_id(1), result: Ok(()) })
.await
.unwrap();
let result_tx_pvf_1_1 = assert_matches!(
@@ -950,7 +969,7 @@ mod tests {
);
test.from_prepare_queue_tx
.send(prepare::FromQueue::Prepared(artifact_id(2)))
.send(prepare::FromQueue { artifact_id: artifact_id(2), result: Ok(()) })
.await
.unwrap();
let result_tx_pvf_2 = assert_matches!(
@@ -1005,7 +1024,7 @@ mod tests {
);
test.from_prepare_queue_tx
.send(prepare::FromQueue::Prepared(artifact_id(1)))
.send(prepare::FromQueue { artifact_id: artifact_id(1), result: Ok(()) })
.await
.unwrap();