如何响应SIGTERM正常关闭Tokio运行时? [英] How do I gracefully shutdown the Tokio runtime in response to a SIGTERM?

查看:177
本文介绍了如何响应SIGTERM正常关闭Tokio运行时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个main函数,在该函数中,我创建了一个Tokio运行时并在其上运行了两个Future.

I have a main function, where I create a Tokio runtime and run two futures on it.

use tokio;

fn main() {
    let mut runtime = tokio::runtime::Runtime::new().unwrap();

    runtime.spawn(MyMegaFutureNumberOne {});
    runtime.spawn(MyMegaFutureNumberTwo {});

    // Some code to 'join' them after receiving an OS signal
}

我如何收到SIGTERM,等待所有未完成的任务(NotReady s)并退出应用程序?

How do I receive a SIGTERM, wait for all unfinished tasks (NotReadys) and exit the application?

推荐答案

使用信号进行处理是很棘手的事情,要解释如何处理所有可能的情况可能太宽泛了.信号的实现不是跨平台的标准,所以我的回答是针对Linux的.如果您想跨平台,请结合使用POSIX函数sigactionpause.这将为您提供更多控制权.

Dealing with signals is tricky and it would be too broad to explain how to handle all possible cases. The implementation of signals is not standard across platforms, so my answer is specific to Linux. If you want to be more cross-platform, use the POSIX function sigaction combined with pause; this will offer you more control.

一种实现所需目标的方法是使用 tokio_signal 板条箱来捕获信号,例如这个:(文档示例)

One way to achieve what you want is to use the tokio_signal crate to catch signals, like this: (doc example)

extern crate futures;
extern crate tokio;
extern crate tokio_signal;

use futures::prelude::*;
use futures::Stream;
use std::time::{Duration, Instant};
use tokio_signal::unix::{Signal, SIGINT, SIGTERM};

fn main() -> Result<(), Box<::std::error::Error>> {
    let mut runtime = tokio::runtime::Runtime::new()?;

    let sigint = Signal::new(SIGINT).flatten_stream();
    let sigterm = Signal::new(SIGTERM).flatten_stream();

    let stream = sigint.select(sigterm);

    let deadline = tokio::timer::Delay::new(Instant::now() + Duration::from_secs(5))
        .map(|()| println!("5 seconds are over"))
        .map_err(|e| eprintln!("Failed to wait: {}", e));

    runtime.spawn(deadline);

    let (item, _rest) = runtime
        .block_on_all(stream.into_future())
        .map_err(|_| "failed to wait for signals")?;

    let item = item.ok_or("received no signal")?;
    if item == SIGINT {
        println!("received SIGINT");
    } else {
        assert_eq!(item, SIGTERM);
        println!("received SIGTERM");
    }

    Ok(())
}

该程序将等待所有当前任务完成并捕获选定的信号.在Windows上这似乎不起作用,因为它会立即关闭程序.

This program will wait for all current tasks to complete and will catch the selected signals. This doesn't seem to work on Windows as it instantly shuts down the program.

这篇关于如何响应SIGTERM正常关闭Tokio运行时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆