Observable Property
A thread-safe observable property implementation for Rust that allows you to observe changes to values across multiple threads.
Features
-
Thread-safe: Uses
Arc<RwLock<>>for safe concurrent access -
Observer pattern: Subscribe to property changes with callbacks
-
Filtered observers: Only notify when specific conditions are met
-
Async notifications: Non-blocking observer notifications with background threads
-
Panic isolation: Observer panics don't crash the system
-
Type-safe: Generic implementation works with any
Clone + Send + Sync + 'statictype -
Zero dependencies: Uses only Rust standard library
Quick Start
Add this to your Cargo.toml:
[]
= "0.1.0"
Usage
Basic Example
use ObservableProperty;
use Arc;
// Create an observable property
let property = new;
// Subscribe to changes
let observer_id = property.subscribe.unwrap;
// Change the value (triggers observer)
property.set.unwrap; // Prints: Value changed from 42 to 100
// Unsubscribe when done
property.unsubscribe.unwrap;
Multi-threading Example
use ObservableProperty;
use Arc;
use thread;
let property = new;
let property_clone = property.clone;
// Subscribe from one thread
property.subscribe.unwrap;
// Modify from another thread
spawn.join.unwrap;
Filtered Observers
use ObservableProperty;
use Arc;
let counter = new;
// Only notify when value increases
let observer_id = counter.subscribe_filtered.unwrap;
counter.set.unwrap; // Triggers observer: "Increased: 0 -> 5"
counter.set.unwrap; // Does NOT trigger observer
counter.set.unwrap; // Triggers observer: "Increased: 3 -> 10"
Async Notifications
For observers that might perform time-consuming operations, use async notifications to avoid blocking:
use ObservableProperty;
use Arc;
use Duration;
let property = new;
property.subscribe.unwrap;
// This returns immediately even though observer is slow
property.set_async.unwrap;
Complex Types
Observable properties work with any type that implements the required traits:
use ObservableProperty;
use Arc;
let person_property = new;
person_property.subscribe.unwrap;
person_property.set.unwrap;
Error Handling
All operations return Result types with descriptive errors:
use ;
let property = new;
match property.get
Performance Considerations
-
Read operations are very fast and can be performed concurrently from multiple threads
-
Write operations are serialized but optimize for quick lock release
-
Synchronous notifications block the setter until all observers complete
-
Asynchronous notifications return immediately and run observers in background threads
-
Observer panics are isolated and won't affect other observers or crash the system
Examples
Run the included examples to see more usage patterns:
# Basic usage example
# Multithreaded usage with performance comparisons
Safety
This crate is designed with safety as a primary concern:
-
Thread-safe access patterns prevent data races
-
Observer panics are caught and isolated
-
Lock poisoning is properly handled and reported
-
No unsafe code is used
License
Licensed under either of
-
Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
-
MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.