调试Rust中的异步发生器错误

2020-10-24 07:25:28

我的同事Matt Jibson和我最近发现自己不幸地陷入了调试来自Rust编译器的这个严重的异步/等待相关错误的境地:

错误[E0277]:`(dyn Futures::Stream<;Item=std::result::Result<;std::vec::Vec<;repr::Row>;,comm::Error>;>;+std::Marker::Send+std::Marker::Unpin+#39;Static)`无法在线程之间安全共享-->;src/Materialized/src/mux.rs:138:100|138|Async FN Handle_Connection(&;Self,conn:SniffedStream<;TcpStream>;)->;Result<;(),无论如何::Error>;{|_^139||self.handleconnection(Conn).wait140||}。|_^`(dyn Futures::Stream<;Item=std::result::Result<;std::vec::Vec<;repr::Row>;,comm::Error>;>;+std::Marker::Send+Std::Marker::Unpin+';Static)`无法在线程之间安全共享|=帮助:`(Dyn Futures::Stream<;Item=std::result::Result<;std::vec::Vec<;repr::Row>;)没有实现特性`std::Marker::Sync`。,comm::Error>;>;+std::Marker::Send+std::Marker::Unpin+';Static)`=备注:由于对`std::Ptr::Unique<;(Dyn Futures::Stream<;Item=std::result::Result<;std::vec::Vec<;repr::Row>;,comm::Error>;>;+std::Marker::Send+std::Marker::Unpin+#39;Static)>;`=注意:必填,因为它出现在类型`std::Boxed::Box<;(dyn Futures::Stream<;Item=std::result::Result<;std::vec::Vec<;repr::Row>;,comm::Error>;>;+std::Marker::Send+std::Marker::Unpin+';Static)>;中。`=注意:必填,因为它出现在类型`std::option::Option<;std::boxed::Box<;(dyn Futures::Stream<;Item=std::result::Result<;std::vec::Vec<;repr::Row>;,Comm::Error>;>;+std::Marker::Send+std::Marker::Unpin)>;中。`=备注:必需,因为它出现在`coord::Session::Portal`=Note:Required类型中,因为它出现在`&;coord::Session::Portal`=备注`&;coord::Session::Send`的实施要求中,因为它出现在`for<;';t0、';t1、';t2、';t3、';t4、';t5、';t6、';t5、';t6、';t4、';t5、';t6、';t2、';t3、';t4、';t5、';t6、';T7,';t8>;{std::Future::ResumeTy,&;r MUT pgwire::protocol::StateMachine<;pgwire::server::Conn<;ore::netio::SniffedStream<;tokio::net::TcpStream>;>;>;,std::String::String,pgwire::protocol::StateMachine<;pgwire::server::Conn<;ore::netio::SniffedStream<;tokio::net::TcpStream>;>;>;,&;的mut coord::SessionClient,coord::SessionClient,&;t0 coord::Session::Session,&;';t1 MUT coord::Session::Session,&;&;';T2字符串,&;T3 std::string::string,std::option::option<;&;';t4 coord::session::Portal>;,Tokio_postgres::Error::sqlState::sqlState,Iml Futures::Future,(),&;&39;T7 coord::Session::Portal,Iml Futures::Future}`=备注:必需,因为它出现在类型`[Static generator@pgwire::protocol::StateMachine::<;A>;::describe_portal::#0 0:&;mut pgwire::protocol::StateMachine<;pgwire::server::Conn<;ore::netio::SniffedStream<;]中。Tokio::Net::TcpStream>;>;>;,1:std::string::String,<;';r,';s,';t0,';t1,';t2,';T3,';T4,';T5,';T6,';T7,';T8>;{std::Future::ResumeTy,&;';R MUT pgwire::protocol::StateMachine<;pgwire::server::Conn<;ore::netio::SniffedStream<;tokio::net::TcpStream>;>;>;,std::String::String,pgwire::protocol::StateMachine<;pgwire::server::Conn<;ore::netio::SniffedStream<;tokio::net::TcpStream>;>;>;,&;的MUT Coord::SessionClient,Coord::SessionClient,&;&39;T0 coord::session::session,&;';t1mut coord::session::session,&;';t2str,&;';t3 std::string,std::option::option<;&;';t4 coord::session::portal>;,Tokio_postgres::error::sqlstate::SqlState,Impl Futures::Future,(),&;';T7 coord::Session::Portal,Iml Futures::Future}]`=注意:必填,因为它出现在`std::future::from_generator::GenFuture<;[static generator@pgwire::protocol::StateMachine::<;A>;::describe_portal::#0 0:&;mut pgwire::protocol::StateMachine<;pgwire::server::Conn<;ore::netio::SniffedStream<;tokio::net::TcpStream>;>;>;类型中。,1:std::String::<;';r,';s,';t0,';t1,';t2,';T3,';t4,';t5,';t6,';t7,';t8>;{std::Future::ResumeTy,&;r mut pgwire::protocol::StateMachine<;pgwire::server::Conn<;Ore::netio::SniffedStream<;tokio::net::TcpStream>;>;>;,std::String::String,pgwire::protocol::StateMachine<;pgwire::server::Conn<;ore::netio::SniffedStream<;tokio::net::TcpStream>;>;>;,&;的MUT Coord::SessionClient,Coord::SessionClient,&;t0 Coord::Session::Session,&;&39;T1静音代码::Session::Session,&;&;';T2字符串,&;';T3 STD::String::String,STD::Option::Option&l

您可以在GitHub上查看完整协议的详细信息,我将尽最大努力在这里展示一个简化版本。与Rust中的大多数现代网络代码一样,我们的实现完全是异步的,使用最近稳定的异步/等待语法。

Struct session{portals:HashMap<;string,Portal&>,}struct Portal{SQL:string,Row_Rows:Option<;Vec<;Row>;,}Async FN Execute_Query(SQL:&;str)->;Result<;vec<;Row>;,Error>;{/*...*/}异步FN HANDLE_EXECUTE(CONN:CONN,SESSION:SESSION,PORTAL_NAME:&;STR,MAX_ROWS:usize,)->;result<;(),Error>;{let portal=match session.portals.get_mut(Portal_Name){ome(Portal)=>;portal,NONE=>;baal!(";未知端口。

.