actix Actor怎么会有PyO3 Python?

2024-06-01 04:59:05 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

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

有没有参与者或上下文有对象需要生命参数的方式?在

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();
}

此代码无法使用此错误进行编译。在

^{pr2}$

Tags: 对象newwsuseextern解释器actorlet
2条回答

Actor trait的定义是

pub trait Actor: Sized + 'static { ... }

也就是说,你的生命周期'a必须是'static。在

这里有一个小example

^{pr2}$

正如Nikolay所说,您可以将Py<PyList>对象存储在WsActor中。 为了恢复PyList,您可以再次获得GIL并调用AsPyReftrait的.as_ref(python)方法(这是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();
}

相关问题 更多 >