| Crates.io | moduforge-state |
| lib.rs | moduforge-state |
| version | 0.5.0 |
| created_at | 2025-04-07 11:10:56.661159+00 |
| updated_at | 2025-08-19 09:22:31.665498+00 |
| description | 不可变数据结构与事务系统基础 |
| homepage | https://github.com/Cassielxd/moduforge-rs |
| repository | https://github.com/Cassielxd/moduforge-rs |
| max_upload_size | |
| id | 1623969 |
| size | 106,306 |
ModuForge-RS 状态管理包提供了基于不可变数据结构的现代化状态管理系统,支持事务处理、插件扩展、资源管理和实时协作。该包是 ModuForge-RS 框架的核心组件,为应用程序提供可靠、高效的状态管理能力。
ModuForge-RS 状态管理采用不可变数据结构范式,确保状态变更的可预测性和可追溯性。系统基于以下核心设计原则:
im-rs 库实现高效的不可变数据结构┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ State │ │ Transaction │ │ Plugin │
│ (状态管理) │◄──►│ (事务处理) │◄──►│ (插件系统) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Resource │ │ ResourceTable │ │ GothamState │
│ (资源管理) │ │ (资源表) │ │ (框架状态) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
im::HashMap 的不可变状态存储TypeId 的类型安全资源管理tracing 的结构化日志记录[dependencies]
# 不可变数据结构
im = { version = "15.1", features = ["serde"] }
# 序列化
serde = { version = "1.0", features = ["derive", "rc"] }
serde_json = "1.0"
# 异步运行时
tokio = { version = "1.0", features = ["full"] }
async-trait = "0.1"
# 并发和同步
crossbeam = "0.8"
dashmap = "6.1.0"
# 错误处理
anyhow = "1"
thiserror = "2.0.12"
# 日志系统
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tracing-appender = "0.2"
# 时间处理
time = "0.3"
# 数据模型
moduforge-model = "0.4.12"
# 数据转换
moduforge-transform = "0.4.12"
use mf_state::{State, StateConfig, Transaction, init_logging};
use mf_model::{schema::Schema, node_pool::NodePool};
use std::sync::Arc;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 初始化日志系统
init_logging("info", Some("logs/state.log"))?;
// 创建状态配置
let schema = Arc::new(Schema::default());
let state_config = StateConfig {
schema: Some(schema),
doc: None,
stored_marks: None,
plugins: None,
resource_manager: None,
};
// 创建状态实例
let state = State::create(state_config).await?;
// 创建事务
let mut transaction = Transaction::new(&state);
// 添加节点
let node_id = "new_node".to_string();
transaction.add_node(
node_id.clone(),
vec![/* 节点数据 */]
)?;
// 设置元数据
transaction.set_meta("action", "add_node");
transaction.set_meta("user_id", "user_123");
// 应用事务
let result = state.apply(transaction).await?;
println!("事务应用成功,新状态版本: {}", result.state.version);
Ok(())
}
use mf_state::{
plugin::{Plugin, PluginSpec, PluginTrait, StateField},
resource::Resource,
State, Transaction, StateResult
};
use async_trait::async_trait;
use std::sync::Arc;
#[derive(Debug)]
struct MyPluginState {
counter: i32,
}
impl Resource for MyPluginState {}
#[derive(Debug)]
struct MyPlugin;
#[async_trait]
impl PluginTrait for MyPlugin {
async fn filter_transaction(
&self,
tr: &Transaction,
_state: &State,
) -> bool {
// 检查事务是否应该被过滤
!tr.get_meta::<String>("skip_plugin").is_some()
}
async fn append_transaction(
&self,
_trs: &[Transaction],
_old_state: &State,
_new_state: &State,
) -> StateResult<Option<Transaction>> {
// 可以在这里添加额外的事务
Ok(None)
}
}
#[derive(Debug)]
struct MyStateField;
#[async_trait]
impl StateField for MyStateField {
async fn init(
&self,
_config: &StateConfig,
_instance: Option<&State>,
) -> Arc<dyn Resource> {
Arc::new(MyPluginState { counter: 0 })
}
async fn apply(
&self,
_tr: &Transaction,
value: Arc<dyn Resource>,
_old_state: &State,
_new_state: &State,
) -> Arc<dyn Resource> {
// 更新插件状态
if let Some(state) = value.downcast_arc::<MyPluginState>() {
Arc::new(MyPluginState {
counter: state.counter + 1,
})
} else {
value
}
}
}
// 创建插件
let plugin = Plugin::new(PluginSpec {
key: ("my_plugin".to_string(), "v1".to_string()),
tr: Some(Arc::new(MyPlugin)),
state_field: Some(Arc::new(MyStateField)),
priority: 10,
});
use mf_state::{
resource::Resource,
resource_table::ResourceTable,
gotham_state::GothamState,
ops::GlobalResourceManager
};
use std::sync::Arc;
#[derive(Debug, Clone)]
struct MyResource {
data: String,
}
impl Resource for MyResource {}
// 使用资源表
let resource_table = ResourceTable::default();
resource_table.add("my_resource".to_string(), MyResource {
data: "Hello World".to_string(),
});
// 获取资源
if let Some(resource) = resource_table.get::<MyResource>("my_resource") {
println!("资源数据: {}", resource.data);
}
// 使用 Gotham 状态
let gotham_state = GothamState::default();
gotham_state.put(MyResource {
data: "Gotham Resource".to_string(),
});
if let Some(resource) = gotham_state.try_get::<MyResource>() {
println!("Gotham 资源: {}", resource.data);
}
// 使用全局资源管理器
let mut manager = GlobalResourceManager::new();
manager.resource_table.add("global_resource".to_string(), MyResource {
data: "Global Resource".to_string(),
});
use mf_state::StateConfig;
use mf_model::{schema::Schema, node_pool::NodePool, mark::Mark};
use std::sync::Arc;
let config = StateConfig {
// 文档结构定义
schema: Some(Arc::new(Schema::default())),
// 初始文档内容
doc: Some(Arc::new(NodePool::default())),
// 存储的标记
stored_marks: Some(vec![Mark::default()]),
// 插件列表
plugins: Some(vec![/* 插件列表 */]),
// 资源管理器
resource_manager: Some(Arc::new(GlobalResourceManager::new())),
};
use mf_state::init_logging;
// 只输出到控制台
init_logging("debug", None)?;
// 同时输出到文件和控制台
init_logging("info", Some("logs/moduforge.log"))?;
// 不同日志级别
init_logging("trace", Some("logs/detail.log"))?; // 最详细
init_logging("debug", Some("logs/debug.log"))?; // 调试信息
init_logging("info", Some("logs/info.log"))?; // 一般信息
init_logging("warn", Some("logs/warn.log"))?; // 警告信息
init_logging("error", Some("logs/error.log"))?; // 错误信息
im-rs 的结构共享减少内存使用ModuForge-RS 状态管理包提供了完善的错误处理机制:
use mf_state::error::{StateResult, error};
// 自定义错误处理
fn handle_state_error(result: StateResult<State>) -> anyhow::Result<State> {
match result {
Ok(state) => Ok(state),
Err(e) => {
// 记录错误
tracing::error!("状态操作失败: {}", e);
// 根据错误类型进行不同处理
if e.to_string().contains("schema") {
return Err(error::schema_error("Schema 配置错误").into());
}
Err(e)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_state_creation() {
let config = StateConfig::default();
let state = State::create(config).await.unwrap();
assert_eq!(state.version, 1);
}
#[tokio::test]
async fn test_transaction_application() {
let state = State::create(StateConfig::default()).await.unwrap();
let mut transaction = Transaction::new(&state);
// 添加测试步骤
transaction.set_meta("test", "value");
let result = state.apply(transaction).await.unwrap();
assert_eq!(result.state.version, 2);
}
}
#[cfg(test)]
mod integration_tests {
use super::*;
#[tokio::test]
async fn test_plugin_integration() {
// 创建带插件的状态
let plugin = create_test_plugin();
let config = StateConfig {
plugins: Some(vec![Arc::new(plugin)]),
..Default::default()
};
let state = State::create(config).await.unwrap();
// 测试插件功能
let mut transaction = Transaction::new(&state);
transaction.set_meta("plugin_test", "value");
let result = state.apply(transaction).await.unwrap();
assert!(result.state.has_field("test_plugin"));
}
}
use mf_state::{State, Transaction};
use std::time::Instant;
async fn monitor_transaction_performance(state: &State, transaction: Transaction) {
let start = Instant::now();
let result = state.apply(transaction).await.unwrap();
let duration = start.elapsed();
tracing::info!(
"事务处理完成 - 版本: {}, 耗时: {:?}",
result.state.version,
duration
);
}
use mf_state::State;
fn debug_state(state: &State) {
tracing::debug!("状态信息:");
tracing::debug!(" 版本: {}", state.version);
tracing::debug!(" 字段数量: {}", state.fields_instances.len());
tracing::debug!(" 插件数量: {}", state.plugins().len());
tracing::debug!(" 文档节点数: {}", state.doc().len());
}
State: 主状态管理结构体StateConfig: 状态配置结构体Transaction: 事务处理结构体Plugin: 插件结构体Resource: 资源特征ResourceTable: 资源表结构体GothamState: Gotham 框架状态create(config): 创建新状态apply(transaction): 应用事务get_field(name): 获取字段serialize(): 序列化状态deserialize(data, config): 反序列化状态new(state): 创建新事务add_node(parent_id, nodes): 添加节点remove_node(parent_id, node_ids): 删除节点set_node_attribute(id, values): 设置节点属性add_mark(id, marks): 添加标记remove_mark(id, mark_types): 删除标记set_meta(key, value): 设置元数据get_meta(key): 获取元数据new(spec): 创建新插件get_state(state): 获取插件状态apply_filter_transaction(tr, state): 应用事务过滤apply_append_transaction(trs, old_state, new_state): 应用事务追加我们欢迎社区贡献!请查看以下指南:
本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情。