Skip to main content

lnc_client/
lib.rs

1//! # lnc-client
2//!
3//! Async Rust client library for the [LANCE](https://github.com/nitecon/lance) streaming platform.
4//!
5//! LANCE is a high-performance, non-blocking stream engine designed for 100Gbps sustained
6//! ingestion with sub-microsecond P99 latency.
7//!
8//! ## Features
9//!
10//! - **Async/await** - Built on Tokio for high-performance async I/O
11//! - **Producer** - Batch records with configurable batching and backpressure
12//! - **Consumer** - Standalone ([`standalone`]) and grouped ([`grouped`]) consumer modes
13//! - **Connection pooling** - Automatic reconnection and cluster-aware routing
14//! - **TLS support** - Secure connections with rustls
15//! - **Zero-copy** - Efficient record parsing with minimal allocations
16//!
17//! ## Quick Start
18//!
19//! ### Producer
20//!
21//! ```rust,no_run
22//! use lnc_client::{Producer, ProducerConfig};
23//!
24//! #[tokio::main]
25//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
26//!     let producer = Producer::connect("127.0.0.1:1992", ProducerConfig::new()).await?;
27//!     
28//!     producer.send(1, b"Hello, LANCE!").await?;
29//!     producer.flush().await?;
30//!     producer.close().await?;
31//!     
32//!     Ok(())
33//! }
34//! ```
35//!
36//! ### Consumer (Standalone)
37//!
38//! For independent consumption with manual offset control:
39//!
40//! ```rust,no_run
41//! use lnc_client::{StandaloneConsumer, StandaloneConfig};
42//! use std::path::Path;
43//!
44//! #[tokio::main]
45//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
46//!     let mut consumer = StandaloneConsumer::connect(
47//!         "127.0.0.1:1992",
48//!         StandaloneConfig::new("my-consumer", 1)
49//!             .with_offset_dir(Path::new("/var/lib/lance/offsets")),
50//!     ).await?;
51//!     
52//!     loop {
53//!         if let Some(records) = consumer.next_batch().await? {
54//!             // Process records
55//!             for chunk in records.data.chunks(256) {
56//!                 println!("Received {} bytes", chunk.len());
57//!             }
58//!             consumer.commit().await?;
59//!         }
60//!     }
61//! }
62//! ```
63//!
64//! ### Consumer (Grouped)
65//!
66//! ```rust,no_run
67//! use lnc_client::{AssignmentStrategy, GroupCoordinator, GroupConfig, GroupedConsumer, WorkerConfig};
68//!
69//! #[tokio::main]
70//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
71//!     // Start coordinator (typically one per consumer group)
72//!     let coordinator = GroupCoordinator::start(
73//!         "127.0.0.1:1992",
74//!         GroupConfig::new("my-group")
75//!             .with_topics(vec![1, 2, 3])
76//!             .with_assignment_strategy(AssignmentStrategy::RoundRobin),
77//!     ).await?;
78//!
79//!     // Workers join the group
80//!     let mut worker = GroupedConsumer::join(
81//!         "127.0.0.1:1992",
82//!         coordinator.join_address(),
83//!         WorkerConfig::new("worker-1"),
84//!     ).await?;
85//!
86//!     // Worker processes assigned topics
87//!     loop {
88//!         let topics: Vec<u32> = worker.assignments().to_vec();
89//!         for topic_id in topics {
90//!             if let Some(_records) = worker.next_batch(topic_id).await? {
91//!                 worker.commit(topic_id).await?;
92//!             }
93//!         }
94//!     }
95//! }
96//! ```
97//!
98//! ## Modules
99//!
100//! - [`producer`] - High-level producer with batching and async send
101//! - [`standalone`] - Standalone consumer for direct offset control
102//! - [`grouped`] - Grouped consumer with automatic partition assignment
103//! - [`connection`] - Connection pooling and cluster-aware routing
104//! - [`offset`] - Offset storage backends (memory, file-based)
105//! - [`record`] - Record encoding/decoding utilities
106//! - [`tls`] - TLS configuration
107//!
108//! ## Platform Support
109//!
110//! The client library supports all major platforms:
111//! - Linux (x86_64, aarch64)
112//! - macOS (x86_64, aarch64)
113//! - Windows (x86_64)
114//!
115//! > **Note**: The LANCE server requires Linux with io_uring support, but the client works everywhere.
116
117#![deny(clippy::unwrap_used)]
118#![deny(clippy::expect_used)]
119#![warn(missing_docs)]
120
121mod client;
122pub mod connection;
123mod consumer;
124mod error;
125pub mod grouped;
126pub mod offset;
127pub mod producer;
128pub mod record;
129pub mod standalone;
130pub mod tls;
131
132pub use client::{
133    AuthConfig, ClientConfig, ClientStream, CommitResult, FetchResult, LanceClient,
134    SubscribeResult, TopicInfo,
135};
136pub use connection::{
137    ClusterClient, ConnectionPool, ConnectionPoolConfig, PoolStats, PooledClient,
138    ReconnectingClient,
139};
140pub use consumer::{
141    Consumer, ConsumerConfig, PollResult, SeekPosition, StreamingConsumer, StreamingConsumerConfig,
142};
143pub use error::{ClientError, parse_not_leader_error, validate_topic_name};
144pub use grouped::{
145    AssignmentStrategy, GroupConfig, GroupCoordinator, GroupedConsumer, WorkerConfig,
146};
147pub use offset::{
148    CollectingCommitHook, CommitInfo, HookedOffsetStore, LockFileOffsetStore, LoggingCommitHook,
149    MemoryOffsetStore, OffsetStore, PostCommitHook,
150};
151pub use producer::{MetricsSnapshot, Producer, ProducerConfig, ProducerMetrics, SendAck};
152pub use record::{
153    Record, RecordIterator, RecordParseError, RecordParserConfig, RecordType, TLV_HEADER_SIZE,
154    encode_record, parse_record, parse_records,
155};
156pub use standalone::{StandaloneConfig, StandaloneConsumer, StandaloneConsumerBuilder};
157pub use tls::TlsClientConfig;
158
159#[cfg(test)]
160#[allow(clippy::unwrap_used)]
161mod tests;