python - actix Actor怎么会有PyO3 Python?

标签 python rust rust-actix pyo3

我正在尝试创建具有 PyO3 Python 解释器和 Py 对象的 Actix Actor。

问题是创建 python 解释器 actor 的正确方法是什么?

我认为错误是由静态定义的 Actor 特征引起的。 https://docs.rs/actix/0.7.4/actix/trait.Actor.html

有没有Actor或者Context有object需要life参数的方式?

rust 版本:nightly-2018-09-04,actix 版本:0.7.4

这是当前代码。

extern crate actix;
extern crate actix_web;
extern crate pyo3;

use actix::prelude::*;
use actix_web::{http, server, ws, App, HttpRequest, HttpResponse, Error};
use pyo3::{Python, GILGuard, PyList};

struct WsActor<'a> {
    // addr: Addr<PyActor>,
    gil: GILGuard,
    python: Python<'a>,
    pylist: &'a PyList,
}
impl<'a> Actor for WsActor<'a> {
    type Context = ws::WebsocketContext<Self>;
}
fn attach_ws_actor(req: &HttpRequest<()>) -> Result<HttpResponse, Error> {
    let gil = Python::acquire_gil();
    let python = gil.python();
    let pylist = PyList::empty(python);
    let actor = WsActor {gil, python, pylist};
    ws::start(req, actor)
}
fn main() {
    let sys = actix::System::new("example");

    server::new(move || {
        App::new()
            .resource("/ws/", |r| r.method(http::Method::GET).f(attach_ws_actor))
    }).bind("0.0.0.0:9999")
    .unwrap()
        .start();
}

此代码无法编译并出现此错误。

error[E0478]: lifetime bound not satisfied
  --> src/main.rs:15:10
   |
15 | impl<'a> Actor for WsActor<'a> {
   |          ^^^^^
   |
note: lifetime parameter instantiated with the lifetime 'a as defined on the impl at 15:6
  --> src/main.rs:15:6
   |
15 | impl<'a> Actor for WsActor<'a> {
   |      ^^
   = note: but lifetime parameter must outlive the static lifetime

最佳答案

作为Nikolay说,你可以存储 Py<PyList> WsActor 中的对象. 恢复PyList ,您可以再次获取GIL并调用.as_ref(python) AsPyRef的方法|特征(Py<T> 实现)。 示例如下:

extern crate actix;
extern crate actix_web;
extern crate pyo3;

use actix::prelude::*;
use actix_web::{http, server, ws, App, HttpRequest, HttpResponse, Error};
use pyo3::{Python, PyList, Py, AsPyRef};

struct WsActor {
    // addr: Addr<PyActor>,
    pylist: Py<PyList>,
}
impl Actor for WsActor {
    type Context = ws::WebsocketContext<Self>;
}
impl StreamHandler<ws::Message, ws::ProtocolError> for WsActor {
    fn handle(&mut self, _: ws::Message, _: &mut Self::Context) {
        let gil = Python::acquire_gil();
        let python = gil.python();
        let list = self.pylist.as_ref(python);
        println!("{}", list.len());
    }
}

fn attach_ws_actor(req: &HttpRequest<()>) -> Result<HttpResponse, Error> {
    let gil = Python::acquire_gil();
    let python = gil.python();
    let pylist = PyList::empty(python);
    let actor = WsActor {
        pylist: pylist.into()
    };
    ws::start(req, actor)
}

fn main() {
    let sys = actix::System::new("example");

    server::new(move || {
        App::new()
            .resource("/ws/", |r| r.method(http::Method::GET).f(attach_ws_actor))
    }).bind("0.0.0.0:9999")
    .unwrap()
        .start();
}

关于python - actix Actor怎么会有PyO3 Python?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52288565/

相关文章:

python - 在 Selenium (Python) 中使用 XPath 选择器 'following-sibling::text()'

python - 已有背景图像时如何获取前景蒙版

rust - 引用和 Box<T> 在内存中的表示方式有什么区别?

file-upload - 使用 actix-web-Framework 在 Rust 中的网络服务器上上传文件时使用原始文件名保存文件

python - If 语句定义时出错。 (Python)

python - 带有 python api 的 Elasticsearch Percolator

rust - 选项<Receiver> 在上一次循环迭代中移动

rust - 结构方法类型推断

rust - Actix Web 的终身问题