mirror of
https://github.com/nushell/nushell
synced 2024-12-27 21:43:09 +00:00
Polars: Check to see if the cache is empty before enabling GC. More logging (#13286)
There was a bug where anytime the plugin cache remove was called, the plugin gc was turned back on. This probably happened when I added the reference counter logic.
This commit is contained in:
parent
0cfd5fbece
commit
8316a1597e
4 changed files with 112 additions and 5 deletions
16
crates/nu_plugin_polars/src/cache/list.rs
vendored
16
crates/nu_plugin_polars/src/cache/list.rs
vendored
|
@ -16,7 +16,7 @@ impl PluginCommand for ListDF {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
"Lists stored dataframes."
|
"Lists stored polars objects."
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
|
@ -119,6 +119,20 @@ impl PluginCommand for ListDF {
|
||||||
},
|
},
|
||||||
call.head,
|
call.head,
|
||||||
))),
|
))),
|
||||||
|
PolarsPluginObject::NuPolarsTestData(_, _) => Ok(Some(Value::record(
|
||||||
|
record! {
|
||||||
|
"key" => Value::string(key.to_string(), call.head),
|
||||||
|
"columns" => Value::nothing(call.head),
|
||||||
|
"rows" => Value::nothing(call.head),
|
||||||
|
"type" => Value::string("When", call.head),
|
||||||
|
"estimated_size" => Value::nothing(call.head),
|
||||||
|
"span_contents" => Value::string(span_contents.to_string(), call.head),
|
||||||
|
"span_start" => Value::int(call.head.start as i64, call.head),
|
||||||
|
"span_end" => Value::int(call.head.end as i64, call.head),
|
||||||
|
"reference_count" => Value::int(value.reference_count as i64, call.head),
|
||||||
|
},
|
||||||
|
call.head,
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
let vals = vals.into_iter().flatten().collect();
|
let vals = vals.into_iter().flatten().collect();
|
||||||
|
|
90
crates/nu_plugin_polars/src/cache/mod.rs
vendored
90
crates/nu_plugin_polars/src/cache/mod.rs
vendored
|
@ -69,10 +69,12 @@ impl Cache {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
// Once there are no more entries in the cache
|
if lock.is_empty() {
|
||||||
// we can turn plugin gc back on
|
// Once there are no more entries in the cache
|
||||||
debug!("PolarsPlugin: Cache is empty enabling GC");
|
// we can turn plugin gc back on
|
||||||
engine.set_gc_disabled(false).map_err(LabeledError::from)?;
|
debug!("PolarsPlugin: Cache is empty enabling GC");
|
||||||
|
engine.set_gc_disabled(false).map_err(LabeledError::from)?;
|
||||||
|
}
|
||||||
drop(lock);
|
drop(lock);
|
||||||
Ok(removed)
|
Ok(removed)
|
||||||
}
|
}
|
||||||
|
@ -170,3 +172,83 @@ pub(crate) fn cache_commands() -> Vec<Box<dyn PluginCommand<Plugin = PolarsPlugi
|
||||||
Box::new(get::CacheGet),
|
Box::new(get::CacheGet),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
struct MockEngineWrapper {
|
||||||
|
gc_enabled: Rc<RefCell<bool>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MockEngineWrapper {
|
||||||
|
fn new(gc_enabled: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
gc_enabled: Rc::new(RefCell::new(gc_enabled)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gc_enabled(&self) -> bool {
|
||||||
|
*self.gc_enabled.borrow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EngineWrapper for &MockEngineWrapper {
|
||||||
|
fn get_env_var(&self, _key: &str) -> Option<String> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn use_color(&self) -> bool {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_gc_disabled(&self, disabled: bool) -> Result<(), ShellError> {
|
||||||
|
let _ = self.gc_enabled.replace(!disabled);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_remove_plugin_cache_enable() {
|
||||||
|
let mock_engine = MockEngineWrapper::new(false);
|
||||||
|
|
||||||
|
let cache = Cache::default();
|
||||||
|
let mut lock = cache.cache.lock().expect("should be able to acquire lock");
|
||||||
|
let key0 = Uuid::new_v4();
|
||||||
|
lock.insert(
|
||||||
|
key0,
|
||||||
|
CacheValue {
|
||||||
|
uuid: Uuid::new_v4(),
|
||||||
|
value: PolarsPluginObject::NuPolarsTestData(Uuid::new_v4(), "object_0".into()),
|
||||||
|
created: Local::now().into(),
|
||||||
|
span: Span::unknown(),
|
||||||
|
reference_count: 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
let key1 = Uuid::new_v4();
|
||||||
|
lock.insert(
|
||||||
|
key1,
|
||||||
|
CacheValue {
|
||||||
|
uuid: Uuid::new_v4(),
|
||||||
|
value: PolarsPluginObject::NuPolarsTestData(Uuid::new_v4(), "object_1".into()),
|
||||||
|
created: Local::now().into(),
|
||||||
|
span: Span::unknown(),
|
||||||
|
reference_count: 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
drop(lock);
|
||||||
|
|
||||||
|
let _ = cache
|
||||||
|
.remove(&mock_engine, &key0, false)
|
||||||
|
.expect("should be able to remove key0");
|
||||||
|
assert!(!mock_engine.gc_enabled());
|
||||||
|
|
||||||
|
let _ = cache
|
||||||
|
.remove(&mock_engine, &key1, false)
|
||||||
|
.expect("should be able to remove key1");
|
||||||
|
assert!(mock_engine.gc_enabled());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ pub enum PolarsPluginType {
|
||||||
NuExpression,
|
NuExpression,
|
||||||
NuLazyGroupBy,
|
NuLazyGroupBy,
|
||||||
NuWhen,
|
NuWhen,
|
||||||
|
NuPolarsTestData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for PolarsPluginType {
|
impl fmt::Display for PolarsPluginType {
|
||||||
|
@ -37,6 +38,7 @@ impl fmt::Display for PolarsPluginType {
|
||||||
Self::NuExpression => write!(f, "NuExpression"),
|
Self::NuExpression => write!(f, "NuExpression"),
|
||||||
Self::NuLazyGroupBy => write!(f, "NuLazyGroupBy"),
|
Self::NuLazyGroupBy => write!(f, "NuLazyGroupBy"),
|
||||||
Self::NuWhen => write!(f, "NuWhen"),
|
Self::NuWhen => write!(f, "NuWhen"),
|
||||||
|
Self::NuPolarsTestData => write!(f, "NuPolarsTestData"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,6 +50,7 @@ pub enum PolarsPluginObject {
|
||||||
NuExpression(NuExpression),
|
NuExpression(NuExpression),
|
||||||
NuLazyGroupBy(NuLazyGroupBy),
|
NuLazyGroupBy(NuLazyGroupBy),
|
||||||
NuWhen(NuWhen),
|
NuWhen(NuWhen),
|
||||||
|
NuPolarsTestData(Uuid, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PolarsPluginObject {
|
impl PolarsPluginObject {
|
||||||
|
@ -95,6 +98,7 @@ impl PolarsPluginObject {
|
||||||
Self::NuExpression(_) => PolarsPluginType::NuExpression,
|
Self::NuExpression(_) => PolarsPluginType::NuExpression,
|
||||||
Self::NuLazyGroupBy(_) => PolarsPluginType::NuLazyGroupBy,
|
Self::NuLazyGroupBy(_) => PolarsPluginType::NuLazyGroupBy,
|
||||||
Self::NuWhen(_) => PolarsPluginType::NuWhen,
|
Self::NuWhen(_) => PolarsPluginType::NuWhen,
|
||||||
|
Self::NuPolarsTestData(_, _) => PolarsPluginType::NuPolarsTestData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +109,7 @@ impl PolarsPluginObject {
|
||||||
PolarsPluginObject::NuExpression(e) => e.id,
|
PolarsPluginObject::NuExpression(e) => e.id,
|
||||||
PolarsPluginObject::NuLazyGroupBy(lg) => lg.id,
|
PolarsPluginObject::NuLazyGroupBy(lg) => lg.id,
|
||||||
PolarsPluginObject::NuWhen(w) => w.id,
|
PolarsPluginObject::NuWhen(w) => w.id,
|
||||||
|
PolarsPluginObject::NuPolarsTestData(id, _) => *id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,6 +120,9 @@ impl PolarsPluginObject {
|
||||||
PolarsPluginObject::NuExpression(e) => e.into_value(span),
|
PolarsPluginObject::NuExpression(e) => e.into_value(span),
|
||||||
PolarsPluginObject::NuLazyGroupBy(lg) => lg.into_value(span),
|
PolarsPluginObject::NuLazyGroupBy(lg) => lg.into_value(span),
|
||||||
PolarsPluginObject::NuWhen(w) => w.into_value(span),
|
PolarsPluginObject::NuWhen(w) => w.into_value(span),
|
||||||
|
PolarsPluginObject::NuPolarsTestData(id, s) => {
|
||||||
|
Value::string(format!("{id}:{s}"), Span::test_data())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ use std::cmp::Ordering;
|
||||||
use cache::cache_commands;
|
use cache::cache_commands;
|
||||||
pub use cache::{Cache, Cacheable};
|
pub use cache::{Cache, Cacheable};
|
||||||
use dataframe::{stub::PolarsCmd, values::CustomValueType};
|
use dataframe::{stub::PolarsCmd, values::CustomValueType};
|
||||||
|
use log::debug;
|
||||||
use nu_plugin::{EngineInterface, Plugin, PluginCommand};
|
use nu_plugin::{EngineInterface, Plugin, PluginCommand};
|
||||||
|
|
||||||
mod cache;
|
mod cache;
|
||||||
|
@ -41,6 +42,7 @@ impl EngineWrapper for &EngineInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_gc_disabled(&self, disabled: bool) -> Result<(), ShellError> {
|
fn set_gc_disabled(&self, disabled: bool) -> Result<(), ShellError> {
|
||||||
|
debug!("set_gc_disabled called with {disabled}");
|
||||||
EngineInterface::set_gc_disabled(self, disabled)
|
EngineInterface::set_gc_disabled(self, disabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,6 +74,7 @@ impl Plugin for PolarsPlugin {
|
||||||
engine: &EngineInterface,
|
engine: &EngineInterface,
|
||||||
custom_value: Box<dyn CustomValue>,
|
custom_value: Box<dyn CustomValue>,
|
||||||
) -> Result<(), LabeledError> {
|
) -> Result<(), LabeledError> {
|
||||||
|
debug!("custom_value_dropped called {:?}", custom_value);
|
||||||
if !self.disable_cache_drop {
|
if !self.disable_cache_drop {
|
||||||
let id = CustomValueType::try_from_custom_value(custom_value)?.id();
|
let id = CustomValueType::try_from_custom_value(custom_value)?.id();
|
||||||
let _ = self.cache.remove(engine, &id, false);
|
let _ = self.cache.remove(engine, &id, false);
|
||||||
|
|
Loading…
Reference in a new issue