- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 tokio 和 futures-cpupool 编写一个简单的 RPC 服务器。服务器持有一个 BTreeMap
盒装闭包,函数名称作为键。当前的实现非常简单:
pub struct SlackerServiceSync<T>
where T: Send + Sync + 'static
{
functions: Arc<BTreeMap<String, RpcFnSync<T>>>,
pool: CpuPool,
}
impl<T> SlackerServiceSync<T>
where T: Send + Sync + 'static
{
pub fn new(functions: Arc<BTreeMap<String, RpcFnSync<T>>>,
threads: usize)
-> SlackerServiceSync<T> {
let pool = CpuPool::new(threads);
SlackerServiceSync { functions, pool }
}
}
impl<T> Service for SlackerServiceSync<T>
where T: Send + Sync + 'static
{
type Request = SlackerPacket<T>;
type Response = SlackerPacket<T>;
type Error = io::Error;
type Future = BoxFuture<Self::Response, Self::Error>;
fn call(&self, req: Self::Request) -> Self::Future {
match req {
SlackerPacket::Request(sreq) => {
debug!("getting request: {:?}", sreq.fname);
if let Some(f) = self.functions.get(&sreq.fname) {
self.pool
.spawn_fn(move || -> FutureResult<T, Self::Error> {
ok(f(&sreq.arguments))
})
.and_then(move |result| {
debug!("getting results");
ok(SlackerPacket::Response(SlackerResponse {
version: sreq.version,
code: RESULT_CODE_SUCCESS,
content_type: sreq.content_type,
serial_id: sreq.serial_id,
result: result,
}))
})
.map_err(|_| io::Error::new(io::ErrorKind::Other, "Oneshot canceled"))
.boxed()
} else {
let error = SlackerError {
version: sreq.version,
code: RESULT_CODE_NOT_FOUND,
serial_id: sreq.serial_id,
};
ok(SlackerPacket::Error(error)).boxed()
}
}
SlackerPacket::Ping(ref ping) => {
ok(SlackerPacket::Pong(SlackerPong { version: ping.version })).boxed()
}
_ => err(io::Error::new(io::ErrorKind::InvalidInput, "Unsupported packet")).boxed(),
}
}
}
我目前被 self.functions.get(&sreq.fname)
上的这个生命周期问题阻止了。
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/service.rs:103:49
|
103 | if let Some(f) = self.functions.get(&sreq.fname) {
| ^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 99:55...
--> src/service.rs:99:56
|
99 | fn call(&self, req: Self::Request) -> Self::Future {
| ________________________________________________________^
100 | | match req {
101 | | SlackerPacket::Request(sreq) => {
102 | | debug!("getting request: {:?}", sreq.fname);
... |
133 | | }
134 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/service.rs:103:34
|
103 | if let Some(f) = self.functions.get(&sreq.fname) {
| ^^^^^^^^^^^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[closure@src/service.rs:105:35: 107:36 f:&std::boxed::Box<for<'r> std::ops::Fn(&'r std::vec::Vec<T>) -> T + std::marker::Send + std::marker::Sync>, sreq:packets::SlackerRequest<T>]` will meet its required lifetime bounds
--> src/service.rs:105:26
|
105 | .spawn_fn(move || -> FutureResult<T, Self::Error> {
| ^^^^^^^^
Similar code works without CpuPool .我无法完全理解编译器报告的错误。
最佳答案
事实证明,我需要通过像这样声明 RcpFnSync
将闭包包装到 Arc
中:
pub type RpcFnSync<T> = Arc<Fn(&Vec<T>) -> T + Send + Sync + 'static>;
然后在发送到另一个线程之前克隆它:
fn call(&self, req: Self::Request) -> Self::Future {
match req {
SlackerPacket::Request(sreq) => {
debug!("getting request: {:?}", sreq.fname);
if let Some(fi) = self.functions.get(&sreq.fname) {
let f = fi.clone();
self.pool
.spawn_fn(move || -> FutureResult<Self::Response, Self::Error> {
let result = f(&sreq.arguments);
ok(SlackerPacket::Response(SlackerResponse {
version: sreq.version,
code: RESULT_CODE_SUCCESS,
content_type: sreq.content_type,
serial_id: sreq.serial_id,
result: result,
}))
})
.boxed()
} else {
let error = SlackerError {
version: sreq.version,
code: RESULT_CODE_NOT_FOUND,
serial_id: sreq.serial_id,
};
ok(SlackerPacket::Error(error)).boxed()
}
}
SlackerPacket::Ping(ref ping) => {
ok(SlackerPacket::Pong(SlackerPong { version: ping.version })).boxed()
}
_ => err(io::Error::new(io::ErrorKind::InvalidInput, "Unsupported packet")).boxed(),
}
}
关于rust - CpuPool 的生命周期问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43708422/
我正在使用 tokio 和 futures-cpupool 编写一个简单的 RPC 服务器。服务器持有一个 BTreeMap 盒装闭包,函数名称作为键。当前的实现非常简单: pub struct Sl
我正在创建一个 futures_cpupool::CpuPool,其中每个线程都需要打开数据库连接,这是一个代价高昂的初始化。这些初始化的状态需要在作业之间保持不变,因为它们需要很长时间才能设置。数据
我有以下代码: extern crate futures; extern crate futures_cpupool; extern crate tokio_timer; use std::time:
我在使用 cpu pools 时遇到了奇怪的行为: #[macro_use] extern crate lazy_static; extern crate tokio_core; extern cra
背景 我正在开发一个通过 r2d2 使用 diesel 的 actix-web 应用程序,我不确定如何最好地进行异步查询。我找到了三个看似合理的选项,但不确定哪一个是最好的。 可能的解决方案 同步 A
我是一名优秀的程序员,十分优秀!