为什么Tokio返回错误“在不允许阻塞的上下文中不能删除运行时”?

鲁帕切科

我有一个与远程服务器对话的Tokio客户端,应该可以使连接永久保持活动状态。我已经实现了初始身份验证握手,并发现当测试终止时,我会感到奇怪:

---- test_connect_without_database stdout ----
thread 'test_connect_without_database' panicked at 'Cannot drop a runtime in a context where blocking is not allowed. This happens when a runtime is dropped from within an asynchronous context.', /playground/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-0.3.5/src/runtime/blocking/shutdown.rs:51:21

我对造成这种情况的原因完全不知所措,所以我不知道要为上下文添加哪些其他代码。

这是我的最小可重现示例(Playground):

use std::cell::RefCell;
use std::net::{IpAddr, SocketAddr};
use tokio::net::TcpStream;
use tokio::prelude::*;
use tokio::runtime;

#[derive(PartialEq, Debug)]
pub struct Configuration {
    /// Database username.
    username: String,
    /// Database password.
    password: String,
    /// Database name.
    db_name: String,
    /// IP address for the remove server.
    address: IpAddr,
    /// Remote server port.
    port: u16,
    /// Number of connections to open.
    connections: u16,
}

impl Configuration {
    pub fn new(
        username: &str,
        password: &str,
        db_name: &str,
        address: &str,
        port: u16,
        connections: u16,
    ) -> Result<Configuration, Box<dyn std::error::Error>> {
        let address = address.to_string().parse()?;
        let configuration = Configuration {
            username: username.to_string(),
            password: password.to_string(),
            db_name: db_name.to_string(),
            address,
            port,
            connections,
        };
        Ok(configuration)
    }

    pub fn socket(&self) -> SocketAddr {
        SocketAddr::new(self.address, self.port)
    }
}

#[derive(Debug)]
pub struct Session {
    configuration: Configuration,
    runtime: RefCell<runtime::Runtime>,
}

impl Session {
    fn new(config: Configuration) -> Result<Session, io::Error> {
        let runtime = runtime::Builder::new_multi_thread()
            .worker_threads(6)
            .enable_all()
            .build()?;
        let session = Session {
            configuration: config,
            runtime: RefCell::new(runtime),
        };
        Ok(session)
    }

    fn configuration(&self) -> &Configuration {
        &self.configuration
    }
}

#[derive(Debug)]
pub(crate) struct Connection<'a> {
    /// Socket uses to read and write from.
    session: &'a Session,
    /// Connection to the remote server.
    stream: TcpStream,
    /// Flag that indicates whether the connection is live.
    live: bool,
}

impl<'a> Connection<'a> {
    async fn new(session: &Session) -> Result<Connection<'_>, Box<dyn std::error::Error>> {
        let mut stream = TcpStream::connect(session.configuration().socket()).await?;
        let conn = Connection {
            session,
            stream,
            live: true,
        };

        Ok(conn)
    }

    fn live(&self) -> bool {
        self.live
    }
}

#[tokio::test]
async fn test_connect_without_database() -> Result<(), Box<dyn std::error::Error>> {
    let config = Configuration::new("rust", "", "", "127.0.0.1", 2345, 2).unwrap();
    let session = Session::new(config).unwrap();
    let conn = Connection::new(&session).await?;
    assert!(conn.live());
    Ok(())
}

fn main() {
    println!("{}", 65u8 as char)
}
Shepmaster

如错误消息所述:

从异步上下文中删除运行时会发生这种情况

您已创建嵌套的运行时:

  1. tokio::test
  2. runtime::Builder::new_multi_thread

拥有第二个运行时Session,在异步测试结束时将其丢弃您可以通过以下方法跳过析构函数来观察此情况mem::forget

#[tokio::test]
async fn test_connect_without_database() -> Result<(), Box<dyn std::error::Error>> {
    let config = Configuration::new("rust", "", "", "127.0.0.1", 2345, 2).unwrap();
    let session = Session::new(config).unwrap();
    // Note that the assert was removed! 
    std::mem::forget(session);

    Ok(())
}

不要产生嵌套的运行时,也不要从另一个运行时中删除一个运行时。

也可以看看:

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

什么是“运行时上下文”?

来自分类Dev

在此上下文中不允许使用表,视图或序列引用'SEQUENCE.NEXTVAL'

来自分类Dev

为什么我在Ruby的YAML文件中得到'`parse':(<unknown>):在此上下文中不允许映射值'

来自分类Dev

使用Java反射在运行时上下文中获取所有定义的变量(内部是Voodoo)

来自分类Dev

在此上下文中,元素样式不允许作为元素主体的子元素(<style scoped>未验证)

来自分类Dev

为什么我不能在jboss的根上下文中设置我的应用程序?

来自分类Dev

C#运行时编译错误:在当前上下文中找不到类型'Double'和'Math'/不存在

来自分类Dev

“存在YAML语法错误” ...“在此上下文中不允许使用映射值”

来自分类Dev

yaml文件问题“在此上下文中不允许使用映射值”

来自分类Dev

在Python上下文中什么是运行时?它由什么组成?

来自分类Dev

HTML验证程序错误-在此上下文中,不允许将元素滑块作为元素主体的子级

来自分类Dev

闪亮的输入滑块错误“在没有活动的反应上下文的情况下,不允许进行操作”

来自分类Dev

不允许在API上下文之外运行Revit Extenral应用程序

来自分类Dev

为什么即使我有#[tokio :: main],也会收到错误消息“没有反应堆在运行,必须从Tokio运行时的上下文中调用”?

来自分类Dev

为什么编译器允许在静态上下文中创建非静态类的对象?

来自分类Dev

使用C#中的上下文菜单在运行时删除控件

来自分类Dev

为什么我在Ruby的YAML文件中得到'`parse':(<unknown>):在此上下文中不允许映射值'

来自分类Dev

如何更正matlab错误:在此上下文中不允许使用函数定义

来自分类Dev

在实体框架中在运行时将新模型添加到现有上下文中

来自分类Dev

在此上下文中不允许元素管理作为元素跨度的子元素

来自分类Dev

元素 h3 在此上下文中不允许作为元素标签的子元素。[html]

来自分类Dev

无效的 YAML:在此上下文中不允许映射值:网络:

来自分类Dev

环境上下文中不允许使用 Angular2 打字稿错误初始值设定项

来自分类Dev

在此上下文中不允许表、视图或序列引用“LN_GRAPH_PERC.DATE_RED”

来自分类Dev

“在此上下文中不允许使用子查询。只允许使用标量表达式。”

来自分类Dev

运行 R Shiny 应用程序时出错:没有活动的反应性上下文不允许操作

来自分类Dev

kubectl 补丁请求抛出“在此上下文中不允许映射值”

来自分类Dev

闪亮文档 (HTML) 扫描仪错误:此上下文中不允许映射值

来自分类Dev

yaml.scanner.ScannerError:在此上下文中不允许映射值(Python 黑盒测试帮助)

Related 相关文章

  1. 1

    什么是“运行时上下文”?

  2. 2

    在此上下文中不允许使用表,视图或序列引用'SEQUENCE.NEXTVAL'

  3. 3

    为什么我在Ruby的YAML文件中得到'`parse':(<unknown>):在此上下文中不允许映射值'

  4. 4

    使用Java反射在运行时上下文中获取所有定义的变量(内部是Voodoo)

  5. 5

    在此上下文中,元素样式不允许作为元素主体的子元素(<style scoped>未验证)

  6. 6

    为什么我不能在jboss的根上下文中设置我的应用程序?

  7. 7

    C#运行时编译错误:在当前上下文中找不到类型'Double'和'Math'/不存在

  8. 8

    “存在YAML语法错误” ...“在此上下文中不允许使用映射值”

  9. 9

    yaml文件问题“在此上下文中不允许使用映射值”

  10. 10

    在Python上下文中什么是运行时?它由什么组成?

  11. 11

    HTML验证程序错误-在此上下文中,不允许将元素滑块作为元素主体的子级

  12. 12

    闪亮的输入滑块错误“在没有活动的反应上下文的情况下,不允许进行操作”

  13. 13

    不允许在API上下文之外运行Revit Extenral应用程序

  14. 14

    为什么即使我有#[tokio :: main],也会收到错误消息“没有反应堆在运行,必须从Tokio运行时的上下文中调用”?

  15. 15

    为什么编译器允许在静态上下文中创建非静态类的对象?

  16. 16

    使用C#中的上下文菜单在运行时删除控件

  17. 17

    为什么我在Ruby的YAML文件中得到'`parse':(<unknown>):在此上下文中不允许映射值'

  18. 18

    如何更正matlab错误:在此上下文中不允许使用函数定义

  19. 19

    在实体框架中在运行时将新模型添加到现有上下文中

  20. 20

    在此上下文中不允许元素管理作为元素跨度的子元素

  21. 21

    元素 h3 在此上下文中不允许作为元素标签的子元素。[html]

  22. 22

    无效的 YAML:在此上下文中不允许映射值:网络:

  23. 23

    环境上下文中不允许使用 Angular2 打字稿错误初始值设定项

  24. 24

    在此上下文中不允许表、视图或序列引用“LN_GRAPH_PERC.DATE_RED”

  25. 25

    “在此上下文中不允许使用子查询。只允许使用标量表达式。”

  26. 26

    运行 R Shiny 应用程序时出错:没有活动的反应性上下文不允许操作

  27. 27

    kubectl 补丁请求抛出“在此上下文中不允许映射值”

  28. 28

    闪亮文档 (HTML) 扫描仪错误:此上下文中不允许映射值

  29. 29

    yaml.scanner.ScannerError:在此上下文中不允许映射值(Python 黑盒测试帮助)

热门标签

归档