英文:
How do I solve the error "thread 'main' panicked at 'no current reactor'"?
问题
我正在尝试连接到数据库:
extern crate tokio; // 0.2.6, features = ["full"]
extern crate tokio_postgres; // 0.5.1
use futures::executor;
use tokio_postgres::NoTls;
fn main() {
let fut = async {
let (client, connection) = match tokio_postgres::connect("actual stuff", NoTls).await {
Ok((client, connection)) => (client, connection),
Err(e) => panic!(e),
};
tokio::spawn(async move {
if let Err(e) = connection.await {
eprintln!("connection error: {}", e);
}
});
let rows = match client
.query(
"SELECT $1 FROM planet_osm_point WHERE $1 IS NOT NULL LIMIT 100",
&[&"name"],
)
.await
{
Ok(rows) => rows,
Err(e) => panic!(e),
};
let names: &str = rows[0].get("name");
println!("{:?}", names);
};
executor::block_on(fut);
println!("Hello, world!");
}
它已经编译成功,但当我运行它时,收到了以下错误信息:
thread 'main' panicked at 'no current reactor'
英文:
I am trying to connect to a database:
extern crate tokio; // 0.2.6, features = ["full"]
extern crate tokio_postgres; // 0.5.1
use futures::executor;
use tokio_postgres::NoTls;
fn main() {
let fut = async {
let (client, connection) = match tokio_postgres::connect("actual stuff", NoTls).await {
Ok((client, connection)) => (client, connection),
Err(e) => panic!(e),
};
tokio::spawn(async move {
if let Err(e) = connection.await {
eprintln!("connection error: {}", e);
}
});
let rows = match client
.query(
"SELECT $1 FROM planet_osm_point WHERE $1 IS NOT NULL LIMIT 100",
&[&"name"],
)
.await
{
Ok(rows) => rows,
Err(e) => panic!(e),
};
let names: &str = rows[0].get("name");
println!("{:?}", names);
};
executor::block_on(fut);
println!("Hello, world!");
}
It compiled, but when I ran it, I received the error message
thread 'main' panicked at 'no current reactor'
答案1
得分: 1
当使用许多(但不是全部)Tokio功能时,您必须使用Tokio reactor。在您的代码中,您正在尝试使用由futures crate(executor::block_on
)提供的通用执行器。通常,使用Tokio执行器和reactor是通过使用#[tokio::main]
宏来完成的:
#[tokio::main]
async fn main() {
let (client, connection) = match tokio_postgres::connect("actual stuff", NoTls).await {
Ok((client, connection)) => (client, connection),
Err(e) => panic!(e),
};
tokio::spawn(async move {
if let Err(e) = connection.await {
eprintln!("connection error: {}", e);
}
});
let rows = match client
.query(
"SELECT $1 FROM planet_osm_point WHERE $1 IS NOT NULL LIMIT 100",
&[&"name"],
)
.await
{
Ok(rows) => rows,
Err(e) => panic!(e),
};
let names: &str = rows[0].get("name");
println!("{:?}", names);
}
甚至在tokio_postgres文档的第一个示例中,都向您展示了如何做到这一点:
#[tokio::main] // 默认情况下,tokio_postgres使用tokio crate作为其运行时。
async fn main() -> Result<(), Error> {
这种情况发生的一个原因是因为您正在使用tokio::spawn
,而这个函数文档中有说明:
如果在Tokio运行时之外调用,会引发panic。
另请参阅:
这不会输出您想要的内容:
Err(e) => panic!(e),
您应该使用:
Err(e) => panic!("{}", e),
英文:
When using many (but not all) Tokio features, you must use the Tokio reactor. In your code, you are trying to use the general executor provided by the futures crate (executor::block_on
). Using the Tokio executor and reactor is normally done via use of the #[tokio::main]
macro:
#[tokio::main]
async fn main() {
let (client, connection) = match tokio_postgres::connect("actual stuff", NoTls).await {
Ok((client, connection)) => (client, connection),
Err(e) => panic!(e),
};
tokio::spawn(async move {
if let Err(e) = connection.await {
eprintln!("connection error: {}", e);
}
});
let rows = match client
.query(
"SELECT $1 FROM planet_osm_point WHERE $1 IS NOT NULL LIMIT 100",
&[&"name"],
)
.await
{
Ok(rows) => rows,
Err(e) => panic!(e),
};
let names: &str = rows[0].get("name");
println!("{:?}", names);
}
The very first example in the tokio_postgres docs even shows you how to do this:
>
> #[tokio::main] // By default, tokio_postgres uses the tokio crate as its runtime.
> async fn main() -> Result<(), Error> {
>
One reason this happens is because you are using tokio::spawn
which has this documented:
> Panics if called from outside of the Tokio runtime.
See also:
This doesn't print what you want:
Err(e) => panic!(e),
You want
Err(e) => panic!("{}", e),
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论