Rust调用Web服务时出现的panic错误,线程’actix-rt|system:0|arbiter:0。

huangapple go评论73阅读模式
英文:

rust panic error when calling a web service thread 'actix-rt|system:0|arbiter:0

问题

这是一个简单的REST端点,接受POST输入并调用另一个REST端点。以下是代码的部分翻译:

use actix_web::{web, App, HttpResponse, HttpServer};
use solana_client::rpc_client::RpcClient;
use std::sync::Arc;
use serde::{Deserialize, Serialize};

fn create_rpc_client(endpoint: String) -> RpcClient {
    RpcClient::new(endpoint)
}

#[derive(Debug, Serialize, Deserialize)]
struct EpochInfoRequest {
    network: Option<String>,
}

fn get_current_epoch(rpc_client: Arc<RpcClient>) -> u64 {
    // 获取当前时代信息
    let epoch_info = rpc_client.get_epoch_info().unwrap();
    epoch_info.epoch
}

async fn get_epoch_info(info: web::Json<EpochInfoRequest>) -> HttpResponse {
    // 从请求中获取网络名称
    let network = match &info.network {
        Some(network) => network,
        None => "mainnet", // 如果未提供,默认网络
    };

    // 根据请求路径选择连接到的Solana网络
    let endpoint = match network {
        "devnet" => "https://api.devnet.solana.com".to_string(),
        "testnet" => "https://api.testnet.solana.com".to_string(),
        "mainnet" => "https://api.mainnet-beta.solana.com".to_string(),
        _ => network.to_string(), // 自定义网络
    };

    println!("{}", endpoint);
    let rpc_client = Arc::new(create_rpc_client(endpoint));

    // 获取当前时代
    let current_epoch = get_current_epoch(rpc_client);

    println!("{}", current_epoch);

    HttpResponse::Ok().json(current_epoch)
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(
                web::resource("/epoch")
                    .route(web::post().to(get_epoch_info))
            )
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

在运行程序时,你可以使用curl命令进行测试,如下所示:

curl --header "Content-Type: application/json" \
  --request POST \
  --data '{"network":"testnet"}' \
  http://localhost:8080/epoch

此外,你提供的Error.log看起来是一个Rust程序运行时的错误日志,提供了有关错误的详细信息,但没有翻译内容。如果你需要关于错误的进一步帮助,请提供具体的问题或上下文。

英文:

This is my simple rest endpoint accepts a post input and calls another rest endpoint

use actix_web::{web, App, HttpResponse, HttpServer};
use solana_client::rpc_client::RpcClient;
use std::sync::Arc;
use serde::{Deserialize, Serialize};

fn create_rpc_client(endpoint: String) -&gt; RpcClient {
    RpcClient::new(endpoint)
}

#[derive(Debug, Serialize, Deserialize)]
struct EpochInfoRequest {
    network: Option&lt;String&gt;,
}

fn get_current_epoch(rpc_client: Arc&lt;RpcClient&gt;) -&gt; u64 {
    // Get the current epoch
    let epoch_info = rpc_client.get_epoch_info().unwrap();
    epoch_info.epoch
}

async fn get_epoch_info(info: web::Json&lt;EpochInfoRequest&gt;) -&gt; HttpResponse {
    // Get the network name from the request
    let network = match &amp;info.network {
        Some(network) =&gt; network,
        None =&gt; &quot;mainnet&quot;, // Default network if not provided
    };

    // Choose a Solana network to connect to based on the request path
    let endpoint = match network {
        &quot;devnet&quot; =&gt; &quot;https://api.devnet.solana.com&quot;.to_string(),
        &quot;testnet&quot; =&gt; &quot;https://api.testnet.solana.com&quot;.to_string(),
        &quot;mainnet&quot; =&gt; &quot;https://api.mainnet-beta.solana.com&quot;.to_string(),
        _ =&gt; network.to_string(), // Custom network
    };

    println!(&quot;{}&quot;,endpoint);
    let rpc_client = Arc::new(create_rpc_client(endpoint));

    // Get the current epoch
    let current_epoch = get_current_epoch(rpc_client);

    println!(&quot;{}&quot;,current_epoch);

    HttpResponse::Ok().json(current_epoch)
}


#[actix_web::main]
async fn main() -&gt; std::io::Result&lt;()&gt; {
    HttpServer::new(|| {
        App::new()
            .service(
                web::resource(&quot;/epoch&quot;)
                    .route(web::post().to(get_epoch_info))
            )
    })
    .bind(&quot;127.0.0.1:8080&quot;)?
    .run()
    .await
}

while running the program

❯ curl --header &quot;Content-Type: application/json&quot; \
  --request POST \
  --data &#39;{&quot;network&quot;:&quot;testnet&quot;}&#39; \
  http://localhost:8080/epoch

Error.log

❯ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.44s
Running `target/debug/solana_rpc`
https://api.testnet.solana.com
thread &#39;actix-rt|system:0|arbiter:0&#39; panicked at &#39;can call blocking only when running on the multi-threaded runtime&#39;, /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/solana-client-1.14.16/src/rpc_client.rs:4185:9
stack backtrace:
0: rust_begin_unwind
at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:575:5
1: core::panicking::panic_fmt
at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/panicking.rs:64:14
2: core::panicking::panic_display
at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/panicking.rs:135:5
3: tokio::runtime::scheduler::multi_thread::worker::block_in_place
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/multi_thread/worker.rs:348:9
4: tokio::task::blocking::block_in_place
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/blocking.rs:78:9
5: solana_client::rpc_client::RpcClient::invoke
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/solana-client-1.14.16/src/rpc_client.rs:4185:9
6: solana_client::rpc_client::RpcClient::get_epoch_info
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/solana-client-1.14.16/src/rpc_client.rs:2824:9
7: solana_rpc::get_current_epoch
at ./src/main.rs:17:22
8: solana_rpc::get_epoch_info::{{closure}}
at ./src/main.rs:59:25
9: actix_web::handler::handler_service::{{closure}}::{{closure}}
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-web-4.3.1/src/handler.rs:106:21
10: &lt;core::pin::Pin&lt;P&gt; as core::future::future::Future&gt;::poll
at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/future/future.rs:124:9
11: &lt;actix_web::resource::Resource&lt;T&gt; as actix_web::service::HttpServiceFactory&gt;::register::{{closure}}::{{closure}}
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-web-4.3.1/src/resource.rs:414:27
12: &lt;core::pin::Pin&lt;P&gt; as core::future::future::Future&gt;::poll
at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/future/future.rs:124:9
13: &lt;actix_service::map_err::MapErrFuture&lt;A,Req,F,E&gt; as core::future::future::Future&gt;::poll
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-service-2.0.2/src/map_err.rs:99:9
14: actix_http::h1::dispatcher::InnerDispatcher&lt;T,S,B,X,U&gt;::poll_response
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-http-3.3.1/src/h1/dispatcher.rs:472:27
15: &lt;actix_http::h1::dispatcher::Dispatcher&lt;T,S,B,X,U&gt; as core::future::future::Future&gt;::poll
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-http-3.3.1/src/h1/dispatcher.rs:1145:43
16: &lt;actix_http::service::HttpServiceHandlerResponse&lt;T,S,B,X,U&gt; as core::future::future::Future&gt;::poll
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-http-3.3.1/src/service.rs:780:45
17: &lt;actix_service::and_then::AndThenServiceResponse&lt;A,B,Req&gt; as core::future::future::Future&gt;::poll
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-service-2.0.2/src/and_then.rs:114:37
18: &lt;actix_server::service::StreamService&lt;S,I&gt; as actix_service::Service&lt;(actix_server::worker::WorkerCounterGuard,actix_server::socket::MioStream)&gt;&gt;::call::{{closure}}
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-server-2.2.0/src/service.rs:75:30
19: tokio::runtime::task::core::Core&lt;T,S&gt;::poll::{{closure}}
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/core.rs:223:17
20: tokio::loom::std::unsafe_cell::UnsafeCell&lt;T&gt;::with_mut
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/loom/std/unsafe_cell.rs:14:9
21: tokio::runtime::task::core::Core&lt;T,S&gt;::poll
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/core.rs:212:13
22: tokio::runtime::task::harness::poll_future::{{closure}}
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/harness.rs:476:19
23: &lt;core::panic::unwind_safe::AssertUnwindSafe&lt;F&gt; as core::ops::function::FnOnce&lt;()&gt;&gt;::call_once
at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/panic/unwind_safe.rs:271:9
24: std::panicking::try::do_call
at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:483:40
25: ___rust_try
26: std::panicking::try
at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:447:19
27: std::panic::catch_unwind
at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panic.rs:137:14
28: tokio::runtime::task::harness::poll_future
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/harness.rs:464:18
29: tokio::runtime::task::harness::Harness&lt;T,S&gt;::poll_inner
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/harness.rs:198:27
30: tokio::runtime::task::harness::Harness&lt;T,S&gt;::poll
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/harness.rs:152:15
31: tokio::runtime::task::raw::poll
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/raw.rs:255:5
32: tokio::runtime::task::raw::RawTask::poll
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/raw.rs:200:18
33: tokio::runtime::task::LocalNotified&lt;S&gt;::run
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/mod.rs:394:9
34: tokio::task::local::LocalSet::tick::{{closure}}
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:615:63
35: tokio::runtime::coop::with_budget
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/coop.rs:107:5
36: tokio::runtime::coop::budget
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/coop.rs:73:5
37: tokio::task::local::LocalSet::tick
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:615:31
38: &lt;tokio::task::local::RunUntil&lt;T&gt; as core::future::future::Future&gt;::poll::{{closure}}
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:927:16
39: tokio::task::local::LocalSet::with::{{closure}}
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:684:13
40: std::thread::local::LocalKey&lt;T&gt;::try_with
at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/thread/local.rs:446:16
41: std::thread::local::LocalKey&lt;T&gt;::with
at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/thread/local.rs:422:9
42: tokio::task::local::LocalSet::with
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:667:9
43: &lt;tokio::task::local::RunUntil&lt;T&gt; as core::future::future::Future&gt;::poll
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:913:9
44: tokio::task::local::LocalSet::run_until::{{closure}}
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:573:18
45: &lt;core::pin::Pin&lt;P&gt; as core::future::future::Future&gt;::poll
at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/future/future.rs:124:9
46: tokio::runtime::scheduler::current_thread::CoreGuard::block_on::{{closure}}::{{closure}}::{{closure}}
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:541:57
47: tokio::runtime::coop::with_budget
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/coop.rs:107:5
48: tokio::runtime::coop::budget
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/coop.rs:73:5
49: tokio::runtime::scheduler::current_thread::CoreGuard::block_on::{{closure}}::{{closure}}
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:541:25
50: tokio::runtime::scheduler::current_thread::Context::enter
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:350:19
51: tokio::runtime::scheduler::current_thread::CoreGuard::block_on::{{closure}}
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:540:36
52: tokio::runtime::scheduler::current_thread::CoreGuard::enter::{{closure}}
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:615:57
53: tokio::macros::scoped_tls::ScopedKey&lt;T&gt;::set
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/macros/scoped_tls.rs:61:9
54: tokio::runtime::scheduler::current_thread::CoreGuard::enter
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:615:27
55: tokio::runtime::scheduler::current_thread::CoreGuard::block_on
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:530:19
56: tokio::runtime::scheduler::current_thread::CurrentThread::block_on
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:154:24
57: tokio::runtime::runtime::Runtime::block_on
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/runtime.rs:302:47
58: tokio::task::local::LocalSet::block_on
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:534:9
59: actix_rt::runtime::Runtime::block_on
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-rt-2.8.0/src/runtime.rs:82:9
60: actix_rt::arbiter::Arbiter::with_tokio_rt::{{closure}}
at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-rt-2.8.0/src/arbiter.rs:144:21
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

答案1

得分: 1

solana_client::rpc_client::RpcClient 使用 tokio::task::blocking::block_in_place 来提供同步阻塞的 API。但是 actix-rt 使用的默认运行时是单线程的,不允许阻塞任务。
由于您已经在异步运行时中,我建议您改用 solana_client::nonblocking::rpc_client::RpcClient

- use solana_client::rpc_client::RpcClient;
+ use solana_client::nonblocking::rpc_client::RpcClient;
- fn get_current_epoch(rpc_client: Arc<RpcClient>) -> u64 {
+ async fn get_current_epoch(rpc_client: Arc<RpcClient>) -> u64 {
      // 获取当前时代
-     let epoch_info = rpc_client.get_epoch_info().unwrap();
+     let epoch_info = rpc_client.get_epoch_info().await.unwrap();
      epoch_info.epoch
-     let current_epoch = get_current_epoch(rpc_client);
+     let current_epoch = get_current_epoch(rpc_client).await;
英文:

solana_client::rpc_client::RpcClient uses tokio::task::blocking::block_in_place to provide a synchronous, blocking API. But the default runtime used by actix-rt is single threaded and does not allow blocking tasks.
Since you're in an asynchronous runtime already I suggest you use solana_client::nonblocking::rpc_client::RpcClient instead.

- use solana_client::rpc_client::RpcClient;
+ use solana_client::nonblocking::rpc_client::RpcClient;
- fn get_current_epoch(rpc_client: Arc&lt;RpcClient&gt;) -&gt; u64 {
+ async fn get_current_epoch(rpc_client: Arc&lt;RpcClient&gt;) -&gt; u64 {
      // Get the current epoch
-     let epoch_info = rpc_client.get_epoch_info().unwrap();
+     let epoch_info = rpc_client.get_epoch_info().await.unwrap();
      epoch_info.epoch
-     let current_epoch = get_current_epoch(rpc_client);
+     let current_epoch = get_current_epoch(rpc_client).await;

huangapple
  • 本文由 发表于 2023年3月7日 14:59:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75658837.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定