OxiRS Stream - Real-time RDF Streaming
Status: v0.4.0 - Released 2026-07-19
✨ Production Release: Production-ready with API stability guarantees and comprehensive testing.
Real-time RDF data streaming with support for MQTT 5.0/3.1.1, NATS JetStream, RabbitMQ, Redis Streams, and AWS Kinesis in-tree, plus Kafka and Pulsar via separate adapter crates. Process RDF streams with windowing, aggregation, and pattern matching.
Features
Message Brokers
- MQTT 5.0 / 3.1.1 - IoT and Industry 4.0 integration (Sparkplug B, OPC-UA), with a full MQTT 5.0 property codec (
backend::mqtt::properties) - NATS - Lightweight, high-performance messaging with JetStream persistence
- RabbitMQ - Reliable message queuing
- AWS Kinesis / Redis Streams - Cloud-native and in-memory backends
- Apache Kafka / Apache Pulsar - Quarantined out of the default build per COOLJAPAN Pure Rust Policy v2; available as the separate
oxirs-stream-adapter-rdkafka/oxirs-stream-adapter-pulsarcrates (publish = false, workspace-internal — see Kafka & Pulsar below) - Custom Adapters - Bring your own message broker
Stream Processing
- Windowing - Tumbling, sliding, and session windows
- Aggregation - Count, sum, average over windows
- Pattern Matching - Detect patterns in RDF streams
- Filtering - Stream-based SPARQL filters
Features
- At-Least-Once Delivery - Reliable message processing
- Backpressure - Handle fast producers
- Checkpointing - Resume from failures
- Metrics - Monitor stream performance
Installation
Add to your Cargo.toml:
[]
= "0.3.2"
# Default features enable only the in-memory backend. Turn on the backends you need:
= { = "0.3.2", = ["mqtt", "nats"] }
# `industry40` bundles mqtt + opcua + sparkplug for Industry 4.0 deployments.
# `all-backends` bundles nats + kinesis + redis + rabbitmq + mqtt + opcua.
# Kafka and Pulsar are NOT Cargo features of this crate — see "Kafka & Pulsar" below.
Quick Start
MQTT 5.0: Connect, Publish, and Decode Properties
Requires the mqtt feature (rumqttc-backed, use-rustls TLS).
use ;
use MqttMessageProperties;
use ;
use HashMap;
async
Message Broker Configuration
Kafka & Pulsar (adapter crates)
The in-tree kafka/pulsar Cargo features were removed in the COOLJAPAN Pure Rust
Policy v2 migration (rdkafka/rdkafka-sys/libz-sys and pulsar/native-tls/lz4-sys
are not Pure Rust). The former in-tree backends moved verbatim into two
publish = false, workspace-internal adapter crates that stay API-compatible with the
original in-tree types:
oxirs-stream-adapter-rdkafka—KafkaBackend,KafkaProducerConfig,SaslConfig,SslConfig, schema registry clientoxirs-stream-adapter-pulsar— the former in-treePulsarProducer/PulsarConsumer
Construct oxirs_stream_adapter_rdkafka::KafkaBackend / oxirs_stream_adapter_pulsar::PulsarProducer
directly rather than going through oxirs-stream's own backend enum, which now returns a
typed "moved to the adapter crate" error for the Kafka/Pulsar variants.
NATS
use ;
use ;
let config = NatsConfig ;
Windowing
WindowConfig/WindowType/WindowSize (re-exported from the rsp — RDF Stream
Processing — module) drive the window semantics consumed by RspProcessor.
Tumbling Windows
Fixed-size, non-overlapping windows:
use ;
use Duration;
let config = WindowConfig ;
// Process 60-second windows
Sliding Windows
Overlapping windows:
let config = WindowConfig ;
// Windows: [0-60s], [30-90s], [60-120s], ...
Session Windows
Dynamic windows based on inactivity gaps:
let config = WindowConfig ;
Windows are also count-based via WindowSize::Triples(n) instead of WindowSize::Time(_).
Note on the sections below: the snippets from here through "Performance" sketch the streaming operations this crate implements (filtering, mapping, aggregation, temporal/graph pattern detection, checkpointing, retry/dead-letter handling, and store/query integration) as a single fluent
StreamProcessorbuilder. That flat facade is aspirational and does not exist in the current public API — treat these as conceptual sketches, not compilable code. The real, tested entry points for the same capabilities are:cep_engine(pattern detection, rule engine, event correlation),data_quality(validators, cleansers, profilers),stream_router/dead_letter_queue/event_filter(routing, filtering, DLQ),aggregation::ExactlyOnceAggregator,checkpoint/fault_tolerance(checkpoint coordination and recovery), andstore_integration::RealtimeUpdateManager(pushing stream changes into anoxirs-corestore — the practical equivalent of the SHACL/ARQ integration examples below). Seesrc/lib.rsfor the full, current public API.
Stream Operations
Filtering
use SparqlFilter;
let filter = new?;
let filtered_stream = stream.filter;
Mapping
let transformed_stream = stream.map;
Aggregation
use ;
let processor = builder
.source
.window
.aggregate
.aggregate
.build?;
let results = processor.process.await?;
Pattern Matching
Temporal Patterns
use TemporalPattern;
let pattern = builder
.event
.followed_by
.within
.build?;
let matches = stream.detect_pattern.await?;
Graph Patterns
use GraphPattern;
let pattern = parse?;
let matches = stream.match_pattern.await?;
Reliability
Checkpointing
use CheckpointConfig;
let checkpoint_config = CheckpointConfig ;
let processor = builder
.source
.checkpoint
.build?;
// Automatically recovers from last checkpoint on failure
Error Handling
use ;
let error_policy = ErrorPolicy ;
let processor = builder
.source
.error_policy
.build?;
Integration
With oxirs-shacl (Streaming Validation)
use StreamProcessor;
use ValidationEngine;
let validator = new;
let processor = builder
.source
.window
.validate_with
.build?;
let mut results = processor.process.await?;
while let Some = results.next.await
With oxirs-arq (Stream Queries)
use StreamProcessor;
use StreamingQueryEngine;
let query_engine = new;
let query = r#"
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?person (COUNT(?friend) as ?friendCount)
WHERE {
?person a foaf:Person .
?person foaf:knows ?friend .
}
GROUP BY ?person
HAVING (COUNT(?friend) > 10)
"#;
let processor = builder
.source
.window
.query
.build?;
Performance
Throughput Benchmarks
| Message Broker | Throughput | Latency (p99) |
|---|---|---|
Kafka (oxirs-stream-adapter-rdkafka) |
100K triples/s | 15ms |
| NATS | 80K triples/s | 8ms |
| RabbitMQ | 50K triples/s | 20ms |
Benchmarked on M1 Mac with local brokers
Optimization Tips
// Batch processing
let processor = builder
.source
.batch_size // Process in batches of 1000
.parallelism // 4 parallel workers
.build?;
// Backpressure control
let processor = builder
.source
.buffer_size
.backpressure_strategy
.build?;
Status
Production Release (v0.3.2)
- ✅ MQTT 5.0 property codec (
backend::mqtt::properties) — encode/decode for the PUBLISH-relevant property set (Payload Format Indicator, Message Expiry Interval, Content Type, Response Topic, Correlation Data, Subscription Identifier, Topic Alias, repeatable User Properties), wired intoMqttClient::parse_properties_from_bytes() - ✅ NATS JetStream integration with persisted consumer/offset configuration
- ✅ Kafka/Pulsar available via the separate
oxirs-stream-adapter-{rdkafka,pulsar}crates (COOLJAPAN Pure Rust Policy v2 quarantine — see "Kafka & Pulsar" above) - ✅ Windowing (tumbling/sliding/session/landmark), filtering, and mapping
- ✅ Aggregation operators and pattern matching / CEP engine
- ✅ SPARQL stream federation with
SERVICEbridging to remote endpoints - ✅ Prometheus + OTLP metrics/tracing (
MonitoringConfig.otlp_endpoint, envOTEL_EXPORTER_OTLP_ENDPOINT— replaces the deprecatedopentelemetry-jaegerexporter) for throughput, lag, and error rates - ✅ Exactly-once semantics (Chandy-Lamport checkpointing + idempotent producers + atomic ingress transactions)
- ✅ Distributed stream processing across cluster nodes (Raft-backed operator state via oxirs-cluster)
- ✅ 1747 tests passing (
--all-features), zero warnings
Contributing
Feedback and contributions welcome — see CONTRIBUTING.md.
License
Apache-2.0
See Also
- oxirs-shacl - Stream validation
- oxirs-arq - Stream queries
- oxirs-federate - Federated streams