#![cfg(feature = "ha")]
#[macro_use]
extern crate remdb;
use core::ptr::NonNull;
use remdb::config::{DbConfig, DefaultMemoryAllocator, LogMode, WALConfig};
use remdb::ha::{HAConfig, HARole, ReplicationMode};
use remdb::time_series::TimeSeriesConfig;
use remdb::*;
static mut DB_MEMORY: [u8; 8388608] = [0u8; 8388608];
remdb::table!(
users,
100, primary_key: id,
fields: {
id: u32,
name: str(32), age: u8,
active: bool
}
);
static SLAVE_DB_CONFIG: std::sync::LazyLock<DbConfig> = std::sync::LazyLock::new(|| DbConfig {
tables: vec![users.clone()],
total_memory: 8 * 1024 * 1024,
low_power_mode_supported: false,
low_power_max_records: None,
default_max_records: 1000,
memory_allocator: &DefaultMemoryAllocator,
wal_config: WALConfig {
log_path: "./wal_slave",
log_mode: LogMode::Async,
checkpoint_interval_ms: 60000,
log_file_size_limit: 1 * 1024 * 1024,
log_prealloc_size: 0,
log_segment_size: 1 * 1024 * 1024,
retained_checkpoints: 1,
max_consecutive_invalid: 100,
skip_threshold: 1000,
skip_block_size: 1024 * 1024,
max_skip_attempts: 3,
compression_type: config::WALCompressionType::None,
compression_level: 3,
},
time_series_defaults: TimeSeriesConfig::DEFAULT,
#[cfg(feature = "pubsub")]
pubsub_config: None,
#[cfg(feature = "ha")]
ha_config: Some(HAConfig {
node_id: 2,
ha_role: HARole::Slave,
replication_mode: ReplicationMode::Async,
heartbeat_interval_ms: 1000,
failure_detection_ms: 3000,
sync_timeout_ms: 2000,
master_address: Some("127.0.0.1"),
master_port: Some(5556),
replication_port: 5556,
}),
model_worker_config: Default::default(),
});
fn slave_example() {
println!("\n=== 从节点示例 ===");
unsafe {
memory::allocator::init_global_allocator(DB_MEMORY.as_mut_ptr(), DB_MEMORY.len());
let db = init_global_db(&SLAVE_DB_CONFIG).expect("Failed to initialize database");
for i in 0..15 {
if let Some(ha_manager) = ha::get_ha_manager() {
if let Err(e) = ha_manager.check_status() {
println!("[HA] Slave check status error: {:?}", e);
}
}
std::thread::sleep(std::time::Duration::from_secs(1));
println!("[HA] Slave running, iteration: {}", i + 1);
}
let table = db.get_table(0).expect("Failed to get table");
let record_id = 0;
let mut result_data = [0u8; 40];
match table.get_by_id(record_id, result_data.as_mut_ptr()) {
Ok(_) => {
let result_id = core::ptr::read(result_data.as_ptr() as *const u32);
let result_name = core::str::from_utf8(&result_data[4..36])
.unwrap()
.trim_end_matches(char::from(0));
let result_age = core::ptr::read(result_data.as_ptr().add(36) as *const u8);
let result_active = core::ptr::read(result_data.as_ptr().add(37) as *const bool);
println!("从节点:成功读取到主节点复制的数据");
println!(
"从节点:ID: {}, Name: {}, Age: {}, Active: {}",
result_id, result_name, result_age, result_active
);
}
Err(_) => {
println!("从节点:未能读取到主节点数据");
}
}
ha::shutdown().expect("Failed to shutdown HA manager");
}
println!("从节点示例完成");
}
fn main() {
slave_example();
}