fix: Import*Actor shutsdown properly on error
closes kemitix/trello-to-deck#6
This commit is contained in:
parent
6e7244e1e4
commit
44bc9fbe45
4 changed files with 100 additions and 74 deletions
|
@ -1,15 +1,17 @@
|
|||
use color_eyre::eyre::Context;
|
||||
//
|
||||
use crate::import::rate_limit::{RateLimitActor, RequestToken};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use color_eyre::eyre::Context;
|
||||
use kameo::{actor::ActorRef, mailbox::unbounded::UnboundedMailbox, Actor};
|
||||
|
||||
use crate::{
|
||||
ask, e, f,
|
||||
nextcloud::model::{NextcloudBoardId, NextcloudCardId, NextcloudStackId},
|
||||
ask, f,
|
||||
import::rate_limit::{RateLimitActor, RequestToken},
|
||||
nextcloud::model::{Attachment, NextcloudBoardId, NextcloudCardId, NextcloudStackId},
|
||||
on_actor_start, p,
|
||||
trello::model::{attachment::TrelloAttachment, card::TrelloCardId},
|
||||
FullCtx,
|
||||
};
|
||||
use kameo::actor::ActorRef;
|
||||
use kameo::{mailbox::unbounded::UnboundedMailbox, Actor};
|
||||
|
||||
pub(crate) struct ImportAttachmentActor {
|
||||
ctx: FullCtx,
|
||||
|
@ -40,6 +42,39 @@ impl ImportAttachmentActor {
|
|||
rate_limit_actor,
|
||||
}
|
||||
}
|
||||
|
||||
async fn import_attachment(&self, file_name: &Path) -> color_eyre::Result<Attachment> {
|
||||
let temp_fs = kxio::fs::temp()?;
|
||||
let file_path = temp_fs.base().join(file_name);
|
||||
|
||||
// - - - download the attachment from trello
|
||||
ask!(self.rate_limit_actor, RequestToken)?;
|
||||
let attachment_path = self
|
||||
.ctx
|
||||
.trello_client()
|
||||
.save_attachment(
|
||||
&self.trello_card_id,
|
||||
&self.trello_attachment.id,
|
||||
Some(&file_path),
|
||||
&self.ctx.temp_fs,
|
||||
)
|
||||
.await
|
||||
.with_context(|| f!("saving attachment {}", file_path.display()))?;
|
||||
|
||||
// - - - upload the attachment to nextcloud card
|
||||
tracing::info!("Nextcloud: upload attachment");
|
||||
self.ctx
|
||||
.deck_client()
|
||||
.add_attachment_to_card(
|
||||
self.nextcloud_board_id,
|
||||
self.nextcloud_stack_id,
|
||||
self.nextcloud_card_id,
|
||||
&temp_fs.file(&attachment_path),
|
||||
)
|
||||
.await
|
||||
.result
|
||||
.with_context(|| f!("adding attachment to card {}", file_path.display()))
|
||||
}
|
||||
}
|
||||
impl Actor for ImportAttachmentActor {
|
||||
type Mailbox = UnboundedMailbox<Self>;
|
||||
|
@ -50,61 +85,28 @@ impl Actor for ImportAttachmentActor {
|
|||
">> Adding attachment: {}",
|
||||
this.trello_attachment.name
|
||||
);
|
||||
// - - - download the attachment from trello
|
||||
let file_name = f!(
|
||||
"{}-{}",
|
||||
this.trello_attachment.id,
|
||||
this.trello_attachment.name
|
||||
);
|
||||
let file_path = this.ctx.temp_fs.base().join(&file_name);
|
||||
ask!(this.rate_limit_actor, RequestToken)?; // FIXME: (#6) handle error
|
||||
let attachment_path = this
|
||||
.ctx
|
||||
.trello_client()
|
||||
.save_attachment(
|
||||
&this.trello_card_id,
|
||||
&this.trello_attachment.id,
|
||||
Some(&file_path),
|
||||
&this.ctx.temp_fs,
|
||||
)
|
||||
.await
|
||||
.with_context(|| f!("saving attachment {}", file_path.display()))?; // FIXME: (#6) handle error
|
||||
let attachment_file = this.ctx.temp_fs.file(&attachment_path);
|
||||
// - - - upload the attachment to nextcloud card
|
||||
tracing::info!("Nextcloud: upload attachment");
|
||||
let attachment = this
|
||||
.ctx
|
||||
.deck_client()
|
||||
.add_attachment_to_card(
|
||||
this.nextcloud_board_id,
|
||||
this.nextcloud_stack_id,
|
||||
this.nextcloud_card_id,
|
||||
&attachment_file,
|
||||
)
|
||||
.await
|
||||
.result
|
||||
.inspect_err(|e| {
|
||||
e!(
|
||||
this.ctx.prt,
|
||||
">> Error adding attachment {} to card: {}",
|
||||
file_path.display(),
|
||||
e.to_string()
|
||||
);
|
||||
})
|
||||
.with_context(|| f!("adding attachment to card {}", file_path.display()))?; // FIXME: (#6) handle error
|
||||
p!(
|
||||
this.ctx.prt,
|
||||
">> Attachment added: {}:{}",
|
||||
attachment.id,
|
||||
attachment.attachment_type,
|
||||
// attachment.extended_data.mimetype
|
||||
);
|
||||
// delete local copy of attachment
|
||||
attachment_file
|
||||
.remove()
|
||||
.with_context(|| f!("deleting temp file {attachment_file}"))?; // FIXME: (#6) handle error
|
||||
|
||||
tracing::info!("ImportAttachmentActor finished");
|
||||
match this.import_attachment(&PathBuf::from(file_name)).await {
|
||||
Ok(attachment) => {
|
||||
p!(
|
||||
this.ctx.prt,
|
||||
">> Attachment added: {}:{}",
|
||||
attachment.id,
|
||||
attachment.attachment_type,
|
||||
// attachment.extended_data.mimetype
|
||||
);
|
||||
tracing::info!("ImportAttachmentActor finished");
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::error!(?err);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(actor_ref.stop_gracefully().await?)
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
//
|
||||
use std::collections::HashMap;
|
||||
|
||||
use kameo::{
|
||||
actor::{ActorID, ActorRef},
|
||||
error::ActorStopReason,
|
||||
mailbox::unbounded::UnboundedMailbox,
|
||||
Actor,
|
||||
};
|
||||
|
||||
use crate::nextcloud::model::Card;
|
||||
use crate::{
|
||||
ask,
|
||||
import::{
|
||||
|
@ -27,6 +21,13 @@ use crate::{
|
|||
},
|
||||
FullCtx,
|
||||
};
|
||||
use kameo::{
|
||||
actor::{ActorID, ActorRef},
|
||||
error::ActorStopReason,
|
||||
mailbox::unbounded::UnboundedMailbox,
|
||||
Actor,
|
||||
};
|
||||
use kxio::Error;
|
||||
|
||||
pub(crate) struct ImportCardActor {
|
||||
ctx: FullCtx,
|
||||
|
@ -73,8 +74,9 @@ impl Actor for ImportCardActor {
|
|||
0 => None,
|
||||
_ => Some(NextcloudCardDescription::from(&this.trello_card.desc)),
|
||||
};
|
||||
|
||||
tracing::info!("Nextcloud: Create card");
|
||||
let nextcloud_card = this
|
||||
let nextcloud_card_id = match this
|
||||
.ctx
|
||||
.deck_client()
|
||||
.create_card(
|
||||
|
@ -84,7 +86,14 @@ impl Actor for ImportCardActor {
|
|||
desc.as_ref(),
|
||||
)
|
||||
.await
|
||||
.result?; // FIXME: (#6) handle error
|
||||
.result
|
||||
{
|
||||
Ok(card) => card.id,
|
||||
Err(err) => {
|
||||
tracing::error!(?err);
|
||||
return Ok(actor_ref.stop_gracefully().await?);
|
||||
}
|
||||
};
|
||||
|
||||
let mut limit = RateLimit::new("labels & attachments", 10, 10.0, this.ctx.now());
|
||||
|
||||
|
@ -101,7 +110,7 @@ impl Actor for ImportCardActor {
|
|||
this.ctx.clone(),
|
||||
this.nextcloud_board_id,
|
||||
this.nextcloud_stack_id,
|
||||
nextcloud_card.id,
|
||||
nextcloud_card_id,
|
||||
trello_label,
|
||||
this.labels_actor_ref.clone(),
|
||||
)
|
||||
|
@ -129,7 +138,7 @@ impl Actor for ImportCardActor {
|
|||
this.ctx.clone(),
|
||||
this.nextcloud_board_id,
|
||||
this.nextcloud_stack_id,
|
||||
nextcloud_card.id,
|
||||
nextcloud_card_id,
|
||||
this.trello_card.id.clone(),
|
||||
trello_attachment,
|
||||
this.rate_limit_actor.clone(),
|
||||
|
|
|
@ -41,17 +41,24 @@ impl Actor for ImportLabelActor {
|
|||
type Mailbox = UnboundedMailbox<Self>;
|
||||
|
||||
on_actor_start!(this, actor_ref, {
|
||||
let label_id = ask!(
|
||||
let label_id = match ask!(
|
||||
this.labels_actor_ref,
|
||||
labels::LookupNextcloudLabelId {
|
||||
trello_name: this.trello_label.name.clone(),
|
||||
trello_color: this.trello_label.color.clone()
|
||||
}
|
||||
)?; // FIXME: (#6) handle error
|
||||
) {
|
||||
Ok(label_id) => label_id,
|
||||
Err(err) => {
|
||||
tracing::error!(?err);
|
||||
return Ok(actor_ref.stop_gracefully().await?);
|
||||
}
|
||||
};
|
||||
|
||||
// - - - add the label to the nextcloud card
|
||||
tracing::info!("Nextcloud: add label to card");
|
||||
this.ctx
|
||||
match this
|
||||
.ctx
|
||||
.deck_client()
|
||||
.add_label_to_card(
|
||||
this.nextcloud_board_id,
|
||||
|
@ -60,9 +67,11 @@ impl Actor for ImportLabelActor {
|
|||
label_id,
|
||||
)
|
||||
.await
|
||||
.result?; // FIXME: (#6) handle error
|
||||
|
||||
tracing::info!("ImportLabelActor finished");
|
||||
.result
|
||||
{
|
||||
Ok(_) => tracing::info!("ImportLabelActor finished"),
|
||||
Err(err) => tracing::error!(?err),
|
||||
}
|
||||
Ok(actor_ref.stop_gracefully().await?)
|
||||
});
|
||||
}
|
||||
|
|
|
@ -62,7 +62,10 @@ impl Actor for ImportStackActor {
|
|||
|
||||
crate::p!(this.ctx.prt, "Importing stack: {}", this.trello_stack.name);
|
||||
// - get the list of trello cards in the stack
|
||||
ask!(this.rate_limit_actor, RequestToken)?; // FIXME: (#6) handle error
|
||||
if let Err(err) = ask!(this.rate_limit_actor, RequestToken) {
|
||||
tracing::error!(?err);
|
||||
return Ok(actor_ref.stop_gracefully().await?);
|
||||
}
|
||||
let mut trello_cards = trello_client
|
||||
.list_cards(&TrelloListId::new(this.trello_stack.id.as_ref()))
|
||||
.await
|
||||
|
@ -75,7 +78,10 @@ impl Actor for ImportStackActor {
|
|||
// - for each card in the trello stack
|
||||
for trello_card in trello_cards.into_iter() {
|
||||
limit.block_until_token_available(this.ctx.now()).await;
|
||||
ask!(this.rate_limit_actor, RequestToken)?; // FIXME: (#6) handle error
|
||||
if let Err(err) = ask!(this.rate_limit_actor, RequestToken) {
|
||||
tracing::error!(?err);
|
||||
return Ok(actor_ref.stop_gracefully().await?);
|
||||
}
|
||||
let trello_card_name = trello_card.name.clone();
|
||||
let child: ActorRef<ImportCardActor> = spawn_in_thread!(
|
||||
actor_ref.clone(),
|
||||
|
|
Loading…
Reference in a new issue