feat: support system tasks
This commit is contained in:
@@ -21,8 +21,10 @@ use sea_orm::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
app::AppContextTrait, errors::RecorderResult, models::subscriber_tasks,
|
||||
task::SubscriberTaskTrait,
|
||||
app::AppContextTrait,
|
||||
errors::RecorderResult,
|
||||
models::{subscriber_tasks, system_tasks},
|
||||
task::{SubscriberTaskTrait, SystemTaskTrait},
|
||||
};
|
||||
|
||||
#[derive(
|
||||
@@ -41,7 +43,7 @@ pub enum CronStatus {
|
||||
Failed,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, DeriveEntityModel, PartialEq, Serialize, Deserialize)]
|
||||
#[sea_orm(table_name = "cron")]
|
||||
pub struct Model {
|
||||
#[sea_orm(default_expr = "Expr::current_timestamp()")]
|
||||
@@ -70,6 +72,7 @@ pub struct Model {
|
||||
#[sea_orm(default_expr = "true")]
|
||||
pub enabled: bool,
|
||||
pub subscriber_task: Option<subscriber_tasks::SubscriberTask>,
|
||||
pub system_task: Option<system_tasks::SystemTask>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
@@ -79,7 +82,7 @@ pub enum Relation {
|
||||
from = "Column::SubscriberId",
|
||||
to = "super::subscribers::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "Cascade"
|
||||
on_delete = "Restrict"
|
||||
)]
|
||||
Subscriber,
|
||||
#[sea_orm(
|
||||
@@ -87,9 +90,13 @@ pub enum Relation {
|
||||
from = "Column::SubscriptionId",
|
||||
to = "super::subscriptions::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "Cascade"
|
||||
on_delete = "Restrict"
|
||||
)]
|
||||
Subscription,
|
||||
#[sea_orm(has_many = "super::subscriber_tasks::Entity")]
|
||||
SubscriberTask,
|
||||
#[sea_orm(has_many = "super::system_tasks::Entity")]
|
||||
SystemTask,
|
||||
}
|
||||
|
||||
impl Related<super::subscribers::Entity> for Entity {
|
||||
@@ -104,12 +111,28 @@ impl Related<super::subscriptions::Entity> for Entity {
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::subscriber_tasks::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::SubscriberTask.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::system_tasks::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::SystemTask.def()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]
|
||||
pub enum RelatedEntity {
|
||||
#[sea_orm(entity = "super::subscribers::Entity")]
|
||||
Subscriber,
|
||||
#[sea_orm(entity = "super::subscriptions::Entity")]
|
||||
Subscription,
|
||||
#[sea_orm(entity = "super::subscriber_tasks::Entity")]
|
||||
SubscriberTask,
|
||||
#[sea_orm(entity = "super::system_tasks::Entity")]
|
||||
SystemTask,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -136,6 +159,14 @@ impl ActiveModelBehavior for ActiveModel {
|
||||
"Cron subscriber_id does not match subscriber_task.subscriber_id".to_string(),
|
||||
));
|
||||
}
|
||||
if let ActiveValue::Set(Some(subscriber_id)) = self.subscriber_id
|
||||
&& let ActiveValue::Set(Some(ref system_task)) = self.system_task
|
||||
&& system_task.get_subscriber_id() != Some(subscriber_id)
|
||||
{
|
||||
return Err(DbErr::Custom(
|
||||
"Cron subscriber_id does not match system_task.subscriber_id".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
@@ -219,11 +250,18 @@ impl Model {
|
||||
async fn exec_cron(&self, ctx: &dyn AppContextTrait) -> RecorderResult<()> {
|
||||
if let Some(subscriber_task) = self.subscriber_task.as_ref() {
|
||||
let task_service = ctx.task();
|
||||
let mut new_subscriber_task = subscriber_task.clone();
|
||||
new_subscriber_task.set_cron_id(Some(self.id));
|
||||
task_service
|
||||
.add_subscriber_task(subscriber_task.clone())
|
||||
.add_subscriber_task(new_subscriber_task)
|
||||
.await?;
|
||||
} else if let Some(system_task) = self.system_task.as_ref() {
|
||||
let task_service = ctx.task();
|
||||
let mut new_system_task = system_task.clone();
|
||||
new_system_task.set_cron_id(Some(self.id));
|
||||
task_service.add_system_task(new_system_task).await?;
|
||||
} else {
|
||||
unimplemented!("Cron without subscriber task is not supported now");
|
||||
unimplemented!("Cron without unknown task is not supported now");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
pub mod auth;
|
||||
pub mod bangumi;
|
||||
pub mod credential_3rd;
|
||||
pub mod cron;
|
||||
pub mod downloaders;
|
||||
pub mod downloads;
|
||||
pub mod episodes;
|
||||
@@ -11,4 +12,4 @@ pub mod subscribers;
|
||||
pub mod subscription_bangumi;
|
||||
pub mod subscription_episode;
|
||||
pub mod subscriptions;
|
||||
pub mod cron;
|
||||
pub mod system_tasks;
|
||||
|
||||
@@ -24,13 +24,14 @@ pub enum SubscriberTaskStatus {
|
||||
Killed,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)]
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "subscriber_tasks")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: String,
|
||||
pub subscriber_id: i32,
|
||||
pub subscription_id: Option<i32>,
|
||||
pub cron_id: Option<i32>,
|
||||
pub job: SubscriberTask,
|
||||
pub task_type: SubscriberTaskType,
|
||||
pub status: SubscriberTaskStatus,
|
||||
@@ -51,7 +52,7 @@ pub enum Relation {
|
||||
from = "Column::SubscriberId",
|
||||
to = "super::subscribers::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "Cascade"
|
||||
on_delete = "NoAction"
|
||||
)]
|
||||
Subscriber,
|
||||
#[sea_orm(
|
||||
@@ -62,6 +63,14 @@ pub enum Relation {
|
||||
on_delete = "NoAction"
|
||||
)]
|
||||
Subscription,
|
||||
#[sea_orm(
|
||||
belongs_to = "super::cron::Entity",
|
||||
from = "Column::CronId",
|
||||
to = "super::cron::Column::Id",
|
||||
on_update = "NoAction",
|
||||
on_delete = "NoAction"
|
||||
)]
|
||||
Cron,
|
||||
}
|
||||
|
||||
impl Related<super::subscribers::Entity> for Entity {
|
||||
@@ -76,12 +85,20 @@ impl Related<super::subscriptions::Entity> for Entity {
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::cron::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Cron.def()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]
|
||||
pub enum RelatedEntity {
|
||||
#[sea_orm(entity = "super::subscribers::Entity")]
|
||||
Subscriber,
|
||||
#[sea_orm(entity = "super::subscriptions::Entity")]
|
||||
Subscription,
|
||||
#[sea_orm(entity = "super::cron::Entity")]
|
||||
Cron,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
||||
@@ -45,6 +45,8 @@ pub enum Relation {
|
||||
Feed,
|
||||
#[sea_orm(has_many = "super::subscriber_tasks::Entity")]
|
||||
SubscriberTask,
|
||||
#[sea_orm(has_many = "super::system_tasks::Entity")]
|
||||
SystemTask,
|
||||
}
|
||||
|
||||
impl Related<super::subscriptions::Entity> for Entity {
|
||||
@@ -95,6 +97,12 @@ impl Related<super::subscriber_tasks::Entity> for Entity {
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::system_tasks::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::SystemTask.def()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]
|
||||
pub enum RelatedEntity {
|
||||
#[sea_orm(entity = "super::subscriptions::Entity")]
|
||||
@@ -111,6 +119,8 @@ pub enum RelatedEntity {
|
||||
Feed,
|
||||
#[sea_orm(entity = "super::subscriber_tasks::Entity")]
|
||||
SubscriberTask,
|
||||
#[sea_orm(entity = "super::system_tasks::Entity")]
|
||||
SystemTask,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
|
||||
99
apps/recorder/src/models/system_tasks/mod.rs
Normal file
99
apps/recorder/src/models/system_tasks/mod.rs
Normal file
@@ -0,0 +1,99 @@
|
||||
use async_trait::async_trait;
|
||||
use sea_orm::{ActiveValue, entity::prelude::*};
|
||||
|
||||
pub use crate::task::{
|
||||
SystemTask, SystemTaskInput, SystemTaskType, SystemTaskTypeEnum, SystemTaskTypeVariant,
|
||||
SystemTaskTypeVariantIter,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, DeriveActiveEnum, EnumIter, DeriveDisplay)]
|
||||
#[sea_orm(rs_type = "String", db_type = "Text")]
|
||||
pub enum SystemTaskStatus {
|
||||
#[sea_orm(string_value = "Pending")]
|
||||
Pending,
|
||||
#[sea_orm(string_value = "Scheduled")]
|
||||
Scheduled,
|
||||
#[sea_orm(string_value = "Running")]
|
||||
Running,
|
||||
#[sea_orm(string_value = "Done")]
|
||||
Done,
|
||||
#[sea_orm(string_value = "Failed")]
|
||||
Failed,
|
||||
#[sea_orm(string_value = "Killed")]
|
||||
Killed,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
#[sea_orm(table_name = "system_tasks")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: String,
|
||||
pub subscriber_id: Option<i32>,
|
||||
pub cron_id: Option<i32>,
|
||||
pub job: SystemTask,
|
||||
pub task_type: SystemTaskType,
|
||||
pub status: SystemTaskStatus,
|
||||
pub attempts: i32,
|
||||
pub max_attempts: i32,
|
||||
pub run_at: DateTimeUtc,
|
||||
pub last_error: Option<String>,
|
||||
pub lock_at: Option<DateTimeUtc>,
|
||||
pub lock_by: Option<String>,
|
||||
pub done_at: Option<DateTimeUtc>,
|
||||
pub priority: i32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::subscribers::Entity",
|
||||
from = "Column::SubscriberId",
|
||||
to = "super::subscribers::Column::Id",
|
||||
on_update = "Cascade",
|
||||
on_delete = "Restrict"
|
||||
)]
|
||||
Subscriber,
|
||||
#[sea_orm(
|
||||
belongs_to = "super::cron::Entity",
|
||||
from = "Column::CronId",
|
||||
to = "super::cron::Column::Id",
|
||||
on_update = "NoAction",
|
||||
on_delete = "NoAction"
|
||||
)]
|
||||
Cron,
|
||||
}
|
||||
|
||||
impl Related<super::subscribers::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Subscriber.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::cron::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Cron.def()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelatedEntity)]
|
||||
pub enum RelatedEntity {
|
||||
#[sea_orm(entity = "super::subscribers::Entity")]
|
||||
Subscriber,
|
||||
#[sea_orm(entity = "super::cron::Entity")]
|
||||
Cron,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ActiveModelBehavior for ActiveModel {
|
||||
async fn before_save<C>(mut self, _db: &C, _insert: bool) -> Result<Self, DbErr>
|
||||
where
|
||||
C: ConnectionTrait,
|
||||
{
|
||||
if let ActiveValue::Set(Some(..)) = self.subscriber_id {
|
||||
return Err(DbErr::Custom(
|
||||
"SystemTask can not be created by subscribers now".to_string(),
|
||||
));
|
||||
}
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user