34个版本 (14个重大更新)

0.19.0 2024年7月9日
0.18.0 2024年2月5日
0.17.0 2024年1月18日
0.15.0 2023年4月28日
0.4.1 2018年12月18日

#451 in HTTP服务器

Download history 27/week @ 2024-04-29 19/week @ 2024-05-06 32/week @ 2024-05-13 37/week @ 2024-05-20 22/week @ 2024-05-27 53/week @ 2024-06-03 32/week @ 2024-06-10 17/week @ 2024-06-17 24/week @ 2024-06-24 51/week @ 2024-07-01 130/week @ 2024-07-08 12/week @ 2024-07-15 15/week @ 2024-07-22 22/week @ 2024-07-29 21/week @ 2024-08-05 22/week @ 2024-08-12

每月81次下载
7个crate中使用(通过background-jobs

AGPL-3.0

87KB
1.5K SLoC

后台作业

这个crate提供了从通常同步的应用程序异步运行某些进程所需的工具。这种标准示例是Web服务,其中某些事情需要处理,但在用户等待浏览器响应时处理它们可能不是最佳体验。

用法

将后台作业添加到您的项目

[dependencies]
actix-rt = "2.2.0"
background-jobs = "0.15.0"
serde = { version = "1.0", features = ["derive"] }

要开始使用后台作业,首先您应该定义一个作业。

作业是执行操作所需数据的组合,以及该操作的逻辑。它们实现了Jobserde::Serializeserde::DeserializeOwned

use background_jobs::{Job, BoxError};
use std::future::{ready, Ready};

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct MyJob {
    some_usize: usize,
    other_usize: usize,
}

impl MyJob {
    pub fn new(some_usize: usize, other_usize: usize) -> Self {
        MyJob {
            some_usize,
            other_usize,
        }
    }
}

impl Job for MyJob {
    type State = ();
    type Error = BoxError;
    type Future = Ready<Result<(), BoxError>>;

    const NAME: &'static str = "MyJob";

    fn run(self, _: Self::State) -> Self::Future {
        info!("args: {:?}", self);

        ready(Ok(()))
    }
}

作业的run方法需要一个额外的参数,即作业预期使用的状态。应用程序中定义的所有作业的状态必须相同。默认情况下,状态是一个空元组,但您可能想要传递一些Actix地址或其他东西。

让我们重新定义作业以关注某些应用程序状态。

#[derive(Clone, Debug)]
pub struct MyState {
    pub app_name: String,
}

impl MyState {
    pub fn new(app_name: &str) -> Self {
        MyState {
            app_name: app_name.to_owned(),
        }
    }
}

impl Job for MyJob {
    type State = MyState;
    type Error = BoxError;
    type Future = Ready<Result<(), BoxError>>;

    // The name of the job. It is super important that each job has a unique name,
    // because otherwise one job will overwrite another job when they're being
    // registered.
    const NAME: &'static str = "MyJob";

    // The queue that this processor belongs to
    //
    // Workers have the option to subscribe to specific queues, so this is important to
    // determine which worker will call the processor
    //
    // Jobs can optionally override the queue they're spawned on
    const QUEUE: &'static str = DEFAULT_QUEUE;

    // The number of times background-jobs should try to retry a job before giving up
    //
    // Jobs can optionally override this value
    const MAX_RETRIES: MaxRetries = MaxRetries::Count(1);

    // The logic to determine how often to retry this job if it fails
    //
    // Jobs can optionally override this value
    const BACKOFF: Backoff = Backoff::Exponential(2);

    fn run(self, state: Self::State) -> Self::Future {
        info!("{}: args, {:?}", state.app_name, self);

        ready(Ok(()))
    }
}

运行作业

默认情况下,此crate随background-jobs-actix功能启用。它使用background-jobs-actix crate启动服务器和工作进程,并提供了创建新作业的机制。

background-jobs-actix本身没有存储工作状态的机制。这可以通过实现来自background-jobs-coreStorage trait手动实现,或者可以使用提供的内存存储。

这样我们就说完了,现在回到示例

use background_jobs::{create_server, actix::WorkerConfig, BoxError};

#[actix_rt::main]
async fn main() -> Result<(), BoxError> {
    // Set up our Storage
    // For this example, we use the default in-memory storage mechanism
    use background_jobs::memory_storage::{ActixTimer, Storage};
    let storage = Storage::new(ActixTimer);

    // Configure and start our workers
    let queue_handle = WorkerConfig::new(storage, move || MyState::new("My App"))
        .register::<MyJob>()
        .set_worker_count(DEFAULT_QUEUE, 16)
        .start();

    // Queue our jobs
    queue_handle.queue(MyJob::new(1, 2))?;
    queue_handle.queue(MyJob::new(3, 4))?;
    queue_handle.queue(MyJob::new(5, 6))?;

    // Block on Actix
    actix_rt::signal::ctrl_c().await?;
    Ok(())
}
完整示例

有关完整示例项目,请参阅 示例文件夹

使用自己的服务器/工作实现

如果您想根据这个想法创建自己的作业处理器,可以依赖于提供Job特性和一些其他用于实现作业处理器和作业存储的有用类型的 background-jobs-core crate。

贡献

对于您发现的任何问题,请随时打开问题。请注意,任何贡献的代码都将根据AGPLv3授权。

许可

版权所有 © 2022 Riley Trautman

background-jobs 是免费软件:您可以在自由软件基金会发布的GNU通用公共许可证的条款和条件下重新分发和/或修改它,无论是许可证的第3版,还是(根据您的选择)许可证的任何较新版本。

background-jobs 的分发是希望它将是有用的,但没有任何保证;甚至没有关于适销性和适用于特定目的的暗示保证。有关详细信息,请参阅GNU通用公共许可证。本文件是 background-jobs 的一部分。

您应该已收到GNU通用公共许可证的副本,与 background-jobs 一起。如果没有,请参阅 https://gnu.ac.cn/licenses/

依赖项

~6–15MB
~179K SLoC