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

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

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

问题

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

  1. use actix_web::{web, App, HttpResponse, HttpServer};
  2. use solana_client::rpc_client::RpcClient;
  3. use std::sync::Arc;
  4. use serde::{Deserialize, Serialize};
  5. fn create_rpc_client(endpoint: String) -> RpcClient {
  6. RpcClient::new(endpoint)
  7. }
  8. #[derive(Debug, Serialize, Deserialize)]
  9. struct EpochInfoRequest {
  10. network: Option<String>,
  11. }
  12. fn get_current_epoch(rpc_client: Arc<RpcClient>) -> u64 {
  13. // 获取当前时代信息
  14. let epoch_info = rpc_client.get_epoch_info().unwrap();
  15. epoch_info.epoch
  16. }
  17. async fn get_epoch_info(info: web::Json<EpochInfoRequest>) -> HttpResponse {
  18. // 从请求中获取网络名称
  19. let network = match &info.network {
  20. Some(network) => network,
  21. None => "mainnet", // 如果未提供,默认网络
  22. };
  23. // 根据请求路径选择连接到的Solana网络
  24. let endpoint = match network {
  25. "devnet" => "https://api.devnet.solana.com".to_string(),
  26. "testnet" => "https://api.testnet.solana.com".to_string(),
  27. "mainnet" => "https://api.mainnet-beta.solana.com".to_string(),
  28. _ => network.to_string(), // 自定义网络
  29. };
  30. println!("{}", endpoint);
  31. let rpc_client = Arc::new(create_rpc_client(endpoint));
  32. // 获取当前时代
  33. let current_epoch = get_current_epoch(rpc_client);
  34. println!("{}", current_epoch);
  35. HttpResponse::Ok().json(current_epoch)
  36. }
  37. #[actix_web::main]
  38. async fn main() -> std::io::Result<()> {
  39. HttpServer::new(|| {
  40. App::new()
  41. .service(
  42. web::resource("/epoch")
  43. .route(web::post().to(get_epoch_info))
  44. )
  45. })
  46. .bind("127.0.0.1:8080")?
  47. .run()
  48. .await
  49. }

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

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

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

英文:

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

  1. use actix_web::{web, App, HttpResponse, HttpServer};
  2. use solana_client::rpc_client::RpcClient;
  3. use std::sync::Arc;
  4. use serde::{Deserialize, Serialize};
  5. fn create_rpc_client(endpoint: String) -&gt; RpcClient {
  6. RpcClient::new(endpoint)
  7. }
  8. #[derive(Debug, Serialize, Deserialize)]
  9. struct EpochInfoRequest {
  10. network: Option&lt;String&gt;,
  11. }
  12. fn get_current_epoch(rpc_client: Arc&lt;RpcClient&gt;) -&gt; u64 {
  13. // Get the current epoch
  14. let epoch_info = rpc_client.get_epoch_info().unwrap();
  15. epoch_info.epoch
  16. }
  17. async fn get_epoch_info(info: web::Json&lt;EpochInfoRequest&gt;) -&gt; HttpResponse {
  18. // Get the network name from the request
  19. let network = match &amp;info.network {
  20. Some(network) =&gt; network,
  21. None =&gt; &quot;mainnet&quot;, // Default network if not provided
  22. };
  23. // Choose a Solana network to connect to based on the request path
  24. let endpoint = match network {
  25. &quot;devnet&quot; =&gt; &quot;https://api.devnet.solana.com&quot;.to_string(),
  26. &quot;testnet&quot; =&gt; &quot;https://api.testnet.solana.com&quot;.to_string(),
  27. &quot;mainnet&quot; =&gt; &quot;https://api.mainnet-beta.solana.com&quot;.to_string(),
  28. _ =&gt; network.to_string(), // Custom network
  29. };
  30. println!(&quot;{}&quot;,endpoint);
  31. let rpc_client = Arc::new(create_rpc_client(endpoint));
  32. // Get the current epoch
  33. let current_epoch = get_current_epoch(rpc_client);
  34. println!(&quot;{}&quot;,current_epoch);
  35. HttpResponse::Ok().json(current_epoch)
  36. }
  37. #[actix_web::main]
  38. async fn main() -&gt; std::io::Result&lt;()&gt; {
  39. HttpServer::new(|| {
  40. App::new()
  41. .service(
  42. web::resource(&quot;/epoch&quot;)
  43. .route(web::post().to(get_epoch_info))
  44. )
  45. })
  46. .bind(&quot;127.0.0.1:8080&quot;)?
  47. .run()
  48. .await
  49. }

while running the program

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

Error.log

  1. cargo run
  2. Finished dev [unoptimized + debuginfo] target(s) in 0.44s
  3. Running `target/debug/solana_rpc`
  4. https://api.testnet.solana.com
  5. 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
  6. stack backtrace:
  7. 0: rust_begin_unwind
  8. at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:575:5
  9. 1: core::panicking::panic_fmt
  10. at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/panicking.rs:64:14
  11. 2: core::panicking::panic_display
  12. at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/panicking.rs:135:5
  13. 3: tokio::runtime::scheduler::multi_thread::worker::block_in_place
  14. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/multi_thread/worker.rs:348:9
  15. 4: tokio::task::blocking::block_in_place
  16. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/blocking.rs:78:9
  17. 5: solana_client::rpc_client::RpcClient::invoke
  18. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/solana-client-1.14.16/src/rpc_client.rs:4185:9
  19. 6: solana_client::rpc_client::RpcClient::get_epoch_info
  20. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/solana-client-1.14.16/src/rpc_client.rs:2824:9
  21. 7: solana_rpc::get_current_epoch
  22. at ./src/main.rs:17:22
  23. 8: solana_rpc::get_epoch_info::{{closure}}
  24. at ./src/main.rs:59:25
  25. 9: actix_web::handler::handler_service::{{closure}}::{{closure}}
  26. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-web-4.3.1/src/handler.rs:106:21
  27. 10: &lt;core::pin::Pin&lt;P&gt; as core::future::future::Future&gt;::poll
  28. at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/future/future.rs:124:9
  29. 11: &lt;actix_web::resource::Resource&lt;T&gt; as actix_web::service::HttpServiceFactory&gt;::register::{{closure}}::{{closure}}
  30. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-web-4.3.1/src/resource.rs:414:27
  31. 12: &lt;core::pin::Pin&lt;P&gt; as core::future::future::Future&gt;::poll
  32. at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/future/future.rs:124:9
  33. 13: &lt;actix_service::map_err::MapErrFuture&lt;A,Req,F,E&gt; as core::future::future::Future&gt;::poll
  34. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-service-2.0.2/src/map_err.rs:99:9
  35. 14: actix_http::h1::dispatcher::InnerDispatcher&lt;T,S,B,X,U&gt;::poll_response
  36. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-http-3.3.1/src/h1/dispatcher.rs:472:27
  37. 15: &lt;actix_http::h1::dispatcher::Dispatcher&lt;T,S,B,X,U&gt; as core::future::future::Future&gt;::poll
  38. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-http-3.3.1/src/h1/dispatcher.rs:1145:43
  39. 16: &lt;actix_http::service::HttpServiceHandlerResponse&lt;T,S,B,X,U&gt; as core::future::future::Future&gt;::poll
  40. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-http-3.3.1/src/service.rs:780:45
  41. 17: &lt;actix_service::and_then::AndThenServiceResponse&lt;A,B,Req&gt; as core::future::future::Future&gt;::poll
  42. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-service-2.0.2/src/and_then.rs:114:37
  43. 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}}
  44. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-server-2.2.0/src/service.rs:75:30
  45. 19: tokio::runtime::task::core::Core&lt;T,S&gt;::poll::{{closure}}
  46. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/core.rs:223:17
  47. 20: tokio::loom::std::unsafe_cell::UnsafeCell&lt;T&gt;::with_mut
  48. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/loom/std/unsafe_cell.rs:14:9
  49. 21: tokio::runtime::task::core::Core&lt;T,S&gt;::poll
  50. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/core.rs:212:13
  51. 22: tokio::runtime::task::harness::poll_future::{{closure}}
  52. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/harness.rs:476:19
  53. 23: &lt;core::panic::unwind_safe::AssertUnwindSafe&lt;F&gt; as core::ops::function::FnOnce&lt;()&gt;&gt;::call_once
  54. at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/panic/unwind_safe.rs:271:9
  55. 24: std::panicking::try::do_call
  56. at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:483:40
  57. 25: ___rust_try
  58. 26: std::panicking::try
  59. at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panicking.rs:447:19
  60. 27: std::panic::catch_unwind
  61. at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/panic.rs:137:14
  62. 28: tokio::runtime::task::harness::poll_future
  63. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/harness.rs:464:18
  64. 29: tokio::runtime::task::harness::Harness&lt;T,S&gt;::poll_inner
  65. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/harness.rs:198:27
  66. 30: tokio::runtime::task::harness::Harness&lt;T,S&gt;::poll
  67. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/harness.rs:152:15
  68. 31: tokio::runtime::task::raw::poll
  69. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/raw.rs:255:5
  70. 32: tokio::runtime::task::raw::RawTask::poll
  71. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/raw.rs:200:18
  72. 33: tokio::runtime::task::LocalNotified&lt;S&gt;::run
  73. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/task/mod.rs:394:9
  74. 34: tokio::task::local::LocalSet::tick::{{closure}}
  75. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:615:63
  76. 35: tokio::runtime::coop::with_budget
  77. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/coop.rs:107:5
  78. 36: tokio::runtime::coop::budget
  79. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/coop.rs:73:5
  80. 37: tokio::task::local::LocalSet::tick
  81. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:615:31
  82. 38: &lt;tokio::task::local::RunUntil&lt;T&gt; as core::future::future::Future&gt;::poll::{{closure}}
  83. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:927:16
  84. 39: tokio::task::local::LocalSet::with::{{closure}}
  85. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:684:13
  86. 40: std::thread::local::LocalKey&lt;T&gt;::try_with
  87. at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/thread/local.rs:446:16
  88. 41: std::thread::local::LocalKey&lt;T&gt;::with
  89. at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/std/src/thread/local.rs:422:9
  90. 42: tokio::task::local::LocalSet::with
  91. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:667:9
  92. 43: &lt;tokio::task::local::RunUntil&lt;T&gt; as core::future::future::Future&gt;::poll
  93. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:913:9
  94. 44: tokio::task::local::LocalSet::run_until::{{closure}}
  95. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:573:18
  96. 45: &lt;core::pin::Pin&lt;P&gt; as core::future::future::Future&gt;::poll
  97. at /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/core/src/future/future.rs:124:9
  98. 46: tokio::runtime::scheduler::current_thread::CoreGuard::block_on::{{closure}}::{{closure}}::{{closure}}
  99. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:541:57
  100. 47: tokio::runtime::coop::with_budget
  101. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/coop.rs:107:5
  102. 48: tokio::runtime::coop::budget
  103. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/coop.rs:73:5
  104. 49: tokio::runtime::scheduler::current_thread::CoreGuard::block_on::{{closure}}::{{closure}}
  105. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:541:25
  106. 50: tokio::runtime::scheduler::current_thread::Context::enter
  107. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:350:19
  108. 51: tokio::runtime::scheduler::current_thread::CoreGuard::block_on::{{closure}}
  109. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:540:36
  110. 52: tokio::runtime::scheduler::current_thread::CoreGuard::enter::{{closure}}
  111. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:615:57
  112. 53: tokio::macros::scoped_tls::ScopedKey&lt;T&gt;::set
  113. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/macros/scoped_tls.rs:61:9
  114. 54: tokio::runtime::scheduler::current_thread::CoreGuard::enter
  115. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:615:27
  116. 55: tokio::runtime::scheduler::current_thread::CoreGuard::block_on
  117. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:530:19
  118. 56: tokio::runtime::scheduler::current_thread::CurrentThread::block_on
  119. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/scheduler/current_thread.rs:154:24
  120. 57: tokio::runtime::runtime::Runtime::block_on
  121. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/runtime/runtime.rs:302:47
  122. 58: tokio::task::local::LocalSet::block_on
  123. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.26.0/src/task/local.rs:534:9
  124. 59: actix_rt::runtime::Runtime::block_on
  125. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-rt-2.8.0/src/runtime.rs:82:9
  126. 60: actix_rt::arbiter::Arbiter::with_tokio_rt::{{closure}}
  127. at /Users/anish/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-rt-2.8.0/src/arbiter.rs:144:21
  128. 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

  1. - use solana_client::rpc_client::RpcClient;
  2. + use solana_client::nonblocking::rpc_client::RpcClient;
  1. - fn get_current_epoch(rpc_client: Arc<RpcClient>) -> u64 {
  2. + async fn get_current_epoch(rpc_client: Arc<RpcClient>) -> u64 {
  3. // 获取当前时代
  4. - let epoch_info = rpc_client.get_epoch_info().unwrap();
  5. + let epoch_info = rpc_client.get_epoch_info().await.unwrap();
  6. epoch_info.epoch
  1. - let current_epoch = get_current_epoch(rpc_client);
  2. + 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.

  1. - use solana_client::rpc_client::RpcClient;
  2. + use solana_client::nonblocking::rpc_client::RpcClient;
  1. - fn get_current_epoch(rpc_client: Arc&lt;RpcClient&gt;) -&gt; u64 {
  2. + async fn get_current_epoch(rpc_client: Arc&lt;RpcClient&gt;) -&gt; u64 {
  3. // Get the current epoch
  4. - let epoch_info = rpc_client.get_epoch_info().unwrap();
  5. + let epoch_info = rpc_client.get_epoch_info().await.unwrap();
  6. epoch_info.epoch
  1. - let current_epoch = get_current_epoch(rpc_client);
  2. + 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:

确定