微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Rust /火箭通过变量到端点

如何解决Rust /火箭通过变量到端点

不是我的喜好,但是我今天不得不写一些Rust,所以我试图创建一个只有一个端点的Rocket实例,但是在那个端点上,我需要访问在main期间创建的变量。该变量需要很长时间才能实例化,所以这就是我在此处执行该操作的原因。

我的问题是我找不到安全通过它的方法。无论我做什么,即使该库似乎是线程安全的,编译器仍会抱怨线程安全:https://github.com/brave/adblock-rust/pull/130(在我的本地实例上找到了承诺的代码

这是我得到的错误提示

   |
18 | / lazy_static! {
19 | |     static ref rules_engine: Mutex<Vec<Engine>> = Mutex::new(vec![]);
20 | | }
   | |_^ `std::rc::Rc<std::cell::RefCell<lifeguard::CappedCollection<std::vec::Vec<u64>>>>` cannot be sent between threads safely
   | 

...这是我的代码

#![feature(proc_macro_hygiene,decl_macro)]

#[macro_use]
extern crate rocket;

use std::fs::File;
use std::io::{self,BufRead};
use std::path::Path;

use lazy_static::lazy_static;
use std::sync::Mutex;

use adblock::engine::Engine;
use adblock::lists::FilterFormat;

use rocket::request::{Form,FormError,FormDataError};

lazy_static! {
    static ref rules_engine: Mutex<Vec<Engine>> = Mutex::new(vec![]);
}

fn main() {
    if !Path::new("./rules.txt").exists() {
        println!("rules file does not exist")
    } else {
        println!("loading rules");

        let mut rules = vec![];

        if let Ok(lines) = read_lines("./rules.txt") {
            for line in lines {
                if let Ok(ip) = line {
                    rules.insert(0,ip)
                }
            }

            let eng = Engine::from_rules(&rules,FilterFormat::Standard);
            rules_engine.lock().unwrap().push(eng);
            rocket().launch();
        }
    }
}

#[derive(Debug,FromForm)]
struct FormInput<> {
    #[form(field = "textarea")]
    text_area: String
}

#[post("/",data = "<sink>")]
fn sink(sink: Result<Form<FormInput>,FormError>) -> String {
    match sink {
        Ok(form) => {
            format!("{:?}",&*form)
        }
        Err(FormDataError::Io(_)) => format!("Form input was invalid UTF-8."),Err(FormDataError::Malformed(f)) | Err(FormDataError::Parse(_,f)) => {
            format!("Invalid form input: {}",f)
        }
    }
}

fn rocket() -> rocket::Rocket {
    rocket::ignite().mount("/",routes![sink])
}

fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
    where P: AsRef<Path>,{
    let file = File::open(filename)?;
    Ok(io::BufReader::new(file).lines())
}

eng端点方法中可以使用sink的任何方式?

解决方法

Rc也不是线程安全的,即使在互斥锁后面也是如此。看起来Rc中使用的eng.blocker.pool.poollifeguard::Pool。因此,Engine不是线程安全的(至少默认情况下)。

幸运的是,看来adblock板条箱有一个feature,称为“对象池”,它启用了该特定功能。删除该功能将(希望)使其线程安全。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。