这是一个PyO3的情况。所以Python调用一个长时间运行的任务。使用ZeroMQ消息传递(进程间消息传递 *)用户可以命令任务挂起。此时,我想将“handling framework”对象存储在static
框中,以便用户可能稍后单击“Resume”,通过这样做,回到Rust,在第二次调用时,框架对象可以从这个static
框中检索,并从它停止的地方重新开始工作。2这样做的最大好处是框架的状态可以被保留。
让我感到惊讶的是,Rust内存中的static
结构似乎在Python调用PyO3函数之间保留了下来。
这就是我如何在检测到“suspend”命令时“填充”框架:
static SUSPENDED_FRAMEWORK_OPTION: OnceLock<Box<HandlingFramework>> = OnceLock::new();
...
let mut handling_framework = HandlingFramework::new(op_type, index_name, dir_root_path_str, current_app_version, current_index_version, tx_zero_client);
handling_framework.init()?;
let (job_suspended_state, total_word_count, total_ldoc_count) = handling_framework.index_docs()?;
if std::matches!(job_suspended_state, JobSuspendedState::Suspended) {
let _ = SUSPENDED_FRAMEWORK_OPTION.set(Box::new(handling_framework))
}
字符串
.这就是我试图在稍后的PyO3调用中检索框架的方式:
if op_type == "RESUME".to_string(){
let option_for_framework = SUSPENDED_FRAMEWORK_OPTION.get();
let framework_box_ref = option_for_framework.unwrap();
info!("text_doc_hit_objs_for_processing remaining {}", framework_box_ref.text_doc_hit_objs_for_processing.len());
info!("framework_box_ref type {}", str_type_of(&framework_box_ref));
型
给出framework_box_ref type &alloc::boxed::Box<populate_index::handling_framework::HandlingFramework>
这在某种意义上是可行的,我能够获得对检索到的框架中的各种对象的读访问。
但是要做任何有用的事情(恢复处理),我需要对框架对象有可变的访问权限。我在那里尝试的一切都失败了,通常是沿着“不能移出共享引用”的线路。
我试过这样的方法:
fn unbox<T>(value: Box<T>) -> T {
*value
}
let mut framework = unbox(*framework_box_ref);
型
这给出:
error[E0507]: cannot move out of `*framework_box_ref` which is behind a shared reference
--> src\lib.rs:114:29
|
114 | let mut framework = unbox(*framework_box_ref);
| ^^^^^^^^^^^^^^^^^^ move occurs because `*framework_box_ref` has type `Box<HandlingFramework>`, which does not implement the `Copy` trait
型
有人能建议如何获得这个可变变量吗?目前HandlingFramework
不实现Copy
或Clone
.我已经尝试derive
这些,但有太多的内部字段不实现一个或两个。我可以潜在地实现一个或两个“手动”,如果需要的话,但目前我希望获得可变访问没有...
- 实际上,这不是进程间消息传递,而是线程间消息传递:Rust代码似乎与调用它的Python工作线程在同一个线程中运行。因此,另一个Python线程被用来发送消息。
1条答案
按热度按时间2guxujil1#
如果没有某种内部可变性,就无法写入
OnceLock
中的值,此时您应该使用它而不是OnceLock
。请注意,无论如何都不能从引用移动,即使是&mut
;要做到这一点,您需要交换一些东西,以便referent仍然有效。也不清楚为什么你需要一个
Box
。可以考虑使用
Mutex<Option<_>>
。您可以使用Option::take
来“窃取”Option
的内容,而留下None
。字符串
稍后,您可以像这样取出值:
型
然而,我强烈反对像这样使用全局状态。最好将此值隐藏在表示框架状态的Python对象中,然后您可以从那里获取它,而不需要全局状态。