mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 08:18:18 +00:00
7172e151de
Co-authored-by: heihutu <heihutu@gmail.com> Co-authored-by: houseme <housemecn@gmail.com>
191 lines
6.0 KiB
Rust
191 lines
6.0 KiB
Rust
// Copyright 2024 RustFS Team
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
//! Example demonstrating I/O scheduler usage.
|
|
|
|
use rustfs_io_core::io_profile::StorageMedia;
|
|
use rustfs_io_core::{
|
|
BackpressureMonitor, BackpressureState, DeadlockDetector, IoLoadLevel, IoScheduler, IoSchedulerConfig, KI_B, LockOptimizer,
|
|
LockType, MI_B, calculate_optimal_buffer_size, get_buffer_size_for_media,
|
|
};
|
|
use std::time::Duration;
|
|
|
|
fn main() {
|
|
println!("=== rustfs-io-core Example ===\n");
|
|
|
|
// 1. I/O scheduler example
|
|
io_scheduler_example();
|
|
|
|
// 2. Buffer size calculation example
|
|
buffer_size_example();
|
|
|
|
// 3. Backpressure control example
|
|
backpressure_example();
|
|
|
|
// 4. Deadlock detection example
|
|
deadlock_detection_example();
|
|
|
|
// 5. Lock optimizer example
|
|
lock_optimizer_example();
|
|
}
|
|
|
|
fn io_scheduler_example() {
|
|
println!("--- I/O Scheduler ---");
|
|
|
|
// Create scheduler with configuration
|
|
let config = IoSchedulerConfig {
|
|
max_concurrent_reads: 64,
|
|
base_buffer_size: 64 * KI_B,
|
|
max_buffer_size: MI_B,
|
|
..Default::default()
|
|
};
|
|
let scheduler = IoScheduler::new(config);
|
|
|
|
println!(" Max concurrent reads: {}", scheduler.config().max_concurrent_reads);
|
|
println!(" Base buffer size: {} KB", scheduler.config().base_buffer_size / KI_B);
|
|
println!(" Max buffer size: {} KB", scheduler.config().max_buffer_size / KI_B);
|
|
|
|
// Calculate buffer sizes for different scenarios
|
|
let scenarios = [
|
|
("Small file", 10 * KI_B as i64, true, StorageMedia::Ssd),
|
|
("Medium file", MI_B as i64, true, StorageMedia::Ssd),
|
|
("Large sequential", 100 * MI_B as i64, true, StorageMedia::Ssd),
|
|
("Large random", 100 * MI_B as i64, false, StorageMedia::Ssd),
|
|
("NVMe large", 100 * MI_B as i64, true, StorageMedia::Nvme),
|
|
("HDD large", 100 * MI_B as i64, true, StorageMedia::Hdd),
|
|
];
|
|
|
|
for (name, size, sequential, media) in scenarios {
|
|
let buffer = calculate_optimal_buffer_size(size, 64 * KI_B, sequential, 4, media, IoLoadLevel::Low);
|
|
println!(" {}: {} bytes ({} KB)", name, buffer, buffer / KI_B);
|
|
}
|
|
|
|
println!();
|
|
}
|
|
|
|
fn buffer_size_example() {
|
|
println!("--- Buffer Size Calculation ---");
|
|
|
|
// Comprehensive calculation
|
|
let size1 = calculate_optimal_buffer_size(10 * MI_B as i64, 64 * KI_B, true, 4, StorageMedia::Ssd, IoLoadLevel::Low);
|
|
println!(" Comprehensive (10MB, sequential, SSD): {} KB", size1 / KI_B);
|
|
|
|
// Media type optimization
|
|
let media_types = [
|
|
StorageMedia::Nvme,
|
|
StorageMedia::Ssd,
|
|
StorageMedia::Hdd,
|
|
StorageMedia::Unknown,
|
|
];
|
|
for media in media_types {
|
|
let size = get_buffer_size_for_media(64 * KI_B, media);
|
|
println!(" {} optimized: {} KB", media.as_str(), size / KI_B);
|
|
}
|
|
|
|
println!();
|
|
}
|
|
|
|
fn backpressure_example() {
|
|
println!("--- Backpressure Control ---");
|
|
|
|
let monitor = BackpressureMonitor::with_defaults();
|
|
|
|
// Check initial state
|
|
let state = monitor.state();
|
|
let state_str = match state {
|
|
BackpressureState::Normal => "Normal",
|
|
BackpressureState::Warning => "Warning",
|
|
BackpressureState::Critical => "Critical",
|
|
};
|
|
println!(" Initial state: {}", state_str);
|
|
|
|
// Check if active
|
|
let is_active = monitor.is_active();
|
|
println!(" Backpressure active: {}", is_active);
|
|
|
|
// Try to acquire permit
|
|
if monitor.try_acquire() {
|
|
println!(" Successfully acquired permit");
|
|
monitor.release();
|
|
println!(" Released permit");
|
|
}
|
|
|
|
// View statistics
|
|
println!(" Total processed: {}", monitor.total_processed());
|
|
println!(" Total rejected: {}", monitor.total_rejected());
|
|
|
|
println!();
|
|
}
|
|
|
|
fn deadlock_detection_example() {
|
|
println!("--- Deadlock Detection ---");
|
|
|
|
let detector = DeadlockDetector::with_defaults();
|
|
|
|
// Register locks
|
|
let mutex1 = detector.register_lock(LockType::Mutex);
|
|
let mutex2 = detector.register_lock(LockType::Mutex);
|
|
println!(" Registered locks: mutex1={}, mutex2={}", mutex1, mutex2);
|
|
|
|
// Simulate normal operation
|
|
detector.record_acquire(mutex1, 1); // Thread 1 acquires mutex1
|
|
detector.record_acquire(mutex2, 2); // Thread 2 acquires mutex2
|
|
println!(" Normal operation: no deadlock");
|
|
|
|
// Detect deadlock
|
|
if detector.detect_deadlock().is_none() {
|
|
println!(" Detection result: no deadlock");
|
|
}
|
|
|
|
// Simulate deadlock scenario
|
|
detector.record_wait(mutex2, 1); // Thread 1 waits for mutex2
|
|
detector.record_wait(mutex1, 2); // Thread 2 waits for mutex1
|
|
|
|
// Detect deadlock
|
|
if let Some(deadlock) = detector.detect_deadlock() {
|
|
println!(" Detection result: deadlock found {:?}", deadlock);
|
|
}
|
|
|
|
// Cleanup
|
|
detector.unregister_lock(mutex1);
|
|
detector.unregister_lock(mutex2);
|
|
println!();
|
|
}
|
|
|
|
fn lock_optimizer_example() {
|
|
println!("--- Lock Optimizer ---");
|
|
|
|
let optimizer = LockOptimizer::with_defaults();
|
|
|
|
// Simulate lock operations
|
|
for _i in 0..5 {
|
|
optimizer.on_acquire();
|
|
// Simulate work
|
|
std::thread::sleep(Duration::from_millis(10));
|
|
optimizer.on_release(Duration::from_millis(10));
|
|
}
|
|
|
|
// View statistics
|
|
let stats = optimizer.stats();
|
|
let acquired = stats.total_acquired();
|
|
let avg_hold = stats.avg_hold_time();
|
|
let contention = stats.contention_rate();
|
|
|
|
println!(" Locks acquired: {}", acquired);
|
|
println!(" Average hold time: {:?}", avg_hold);
|
|
println!(" Contention rate: {:.2}%", contention * 100.0);
|
|
|
|
println!();
|
|
}
|