use actix::prelude::*;
use derive_more::Deref as _;
use tracing::Instrument as _;
use crate::messages::MessageToken;
use git_next_core::git;
impl Handler<crate::messages::ValidateRepo> for crate::RepoActor {
type Result = ();
#[tracing::instrument(name = "RepoActor::ValidateRepo", skip_all, fields(repo = %self.repo_details, token = %msg.deref()))]
fn handle(
&mut self,
msg: crate::messages::ValidateRepo,
ctx: &mut Self::Context,
) -> Self::Result {
crate::logger(self.log.as_ref(), "start: ValidateRepo");
match self.token_status(msg.unwrap()) {
TokenStatus::Current => {} TokenStatus::Expired => {
crate::logger(
self.log.as_ref(),
format!("discarded: old message token: {}", self.message_token),
);
return; }
TokenStatus::New(message_token) => {
self.message_token = message_token;
crate::logger(
self.log.as_ref(),
format!("new message token: {}", self.message_token),
);
}
}
crate::logger(
self.log.as_ref(),
format!("accepted token: {}", self.message_token),
);
let Some(ref open_repository) = self.open_repository else {
crate::logger(self.log.as_ref(), "no open repository");
return;
};
crate::logger(self.log.as_ref(), "have open repository");
let Some(repo_config) = self.repo_details.repo_config.clone() else {
crate::logger(self.log.as_ref(), "no repo config");
return;
};
crate::logger(self.log.as_ref(), "have repo config");
match git::validation::positions::validate_positions(
&**open_repository,
&self.repo_details,
repo_config,
) {
Ok(git::validation::positions::Positions {
main,
next,
dev,
dev_commit_history,
}) => {
tracing::debug!(%main, %next, %dev, "positions");
if next != main {
crate::do_send(
ctx.address(),
crate::messages::CheckCIStatus::new(next),
self.log.as_ref(),
);
} else if next != dev {
crate::do_send(
ctx.address(),
crate::messages::AdvanceNext::new((next, dev_commit_history)),
self.log.as_ref(),
)
} else {
}
}
Err(git::validation::positions::Error::Retryable(message)) => {
crate::logger(self.log.as_ref(), message);
let addr = ctx.address();
let message_token = self.message_token;
let sleep_duration = self.sleep_duration;
let log = self.log.clone();
async move {
tracing::debug!("sleeping before retrying...");
crate::logger(log.as_ref(), "before sleep");
tokio::time::sleep(sleep_duration).await;
crate::logger(log.as_ref(), "after sleep");
crate::do_send(
addr,
crate::messages::ValidateRepo::new(message_token),
log.as_ref(),
);
}
.in_current_span()
.into_actor(self)
.wait(ctx);
}
Err(git::validation::positions::Error::UserIntervention(user_notification)) => {
crate::notify_user(
self.notify_user_recipient.as_ref(),
user_notification,
self.log.as_ref(),
)
}
Err(git::validation::positions::Error::NonRetryable(message)) => {
crate::logger(self.log.as_ref(), message);
}
}
}
}
enum TokenStatus {
Current,
Expired,
New(MessageToken),
}
impl crate::RepoActor {
fn token_status(&self, new: MessageToken) -> TokenStatus {
let current = &self.message_token;
if &new > current {
return TokenStatus::New(new);
}
if current > &new {
return TokenStatus::Expired;
}
TokenStatus::Current
}
}