zus-rs 1.1.4

ZUS RPC Framework - Rust implementation with cross-language compatibility
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
# zus-rs: ZUS RPC Framework for Rust

[![Crates.io](https://img.shields.io/crates/v/zus-rs.svg)](https://crates.io/crates/zus-rs)
[![Documentation](https://docs.rs/zus-rs/badge.svg)](https://docs.rs/zus-rs)
[![License](https://img.shields.io/crates/l/zus-rs.svg)](https://github.com/zusrust/zus-rs/blob/main/LICENSE)

**ZUS-RS** is a high-performance, cross-language RPC framework for Rust with compatibility for Java and C++ implementations. It provides service discovery via ZooServer and supports QuickLZ/Snappy compression.

## Features

- ✨ **Cross-Language RPC**: Wire-compatible with Java and C++ implementations
- πŸš€ **High Performance**: Built on Tokio async runtime
- πŸ“¦ **Protocol Buffer**: Efficient binary serialization
- πŸ—œοΈ **Compression**: QuickLZ (default) and Snappy support with smart params-only compression
- πŸ” **Service Discovery**: Integration with ZooServer for dynamic service lookup
- πŸ›‘οΈ **Type Safe**: Full Rust type safety with protobuf definitions
- πŸ“Š **Production Ready**: Tested with comprehensive cross-language test suite

## Quick Start

### Installation

Add `zus-rs` to your `Cargo.toml`:

```toml
[dependencies]
zus-rs = "1.1.4"
tokio = { version = "1.35", features = ["full"] }
```

Or choose specific features:

```toml
# Just client
[dependencies]
zus-rs = { version = "1.1.4", features = ["client"] }

# Just server
[dependencies]
zus-rs = { version = "1.1.4", features = ["server"] }

# Protocol only (no RPC runtime)
[dependencies]
zus-rs = { version = "1.1.4", features = ["protocol"] }
```

## Usage Patterns

ZUS-RS supports **two connection styles**, matching the C++ and Java implementations:

### Style 1: Direct Connection (Without ZooServer)
- **Use when**: You know the exact service address (development, simple deployments)
- **Address format**: `tcp://host:port` or `tcp://host1:port1,host2:port2` (comma-separated for multiple endpoints)
- **No service discovery**: You manage service addresses manually

### Style 2: ZooServer-Based Discovery (With ZooServer)
- **Use when**: You need dynamic service discovery, load balancing, and automatic failover (production)
- **Address format**: `zns://zooserver:port/service/path/`
- **Automatic features**: Service discovery, health checks (every 3s), round-robin load balancing

---

### Client Example - Direct Connection (Style 1)

```rust
use bytes::Bytes;
use zus_rs::RpcClient;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Connect to a single service directly
    let client = RpcClient::new("tcp://localhost:9527").await?;

    // Or connect to multiple endpoints (manual load balancing)
    // let client = RpcClient::new("tcp://host1:9527,host2:9527").await?;

    // Make RPC call
    let request = Bytes::from("Hello, World!");
    let response = client.sync_call("echo", request, 5000).await?;

    println!("Response: {}", String::from_utf8_lossy(&response));
    Ok(())
}
```

### Client Example - ZooServer Discovery (Style 2)

```rust
use bytes::Bytes;
use zus_rs::RpcClient;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Connect via ZooServer - service discovery happens automatically
    let client = RpcClient::new(
        "zns://localhost:9528/zus/services/myservice/"
    ).await?;

    // The client automatically:
    // - Discovers all available service instances from ZooServer
    // - Monitors their health (every 3 seconds)
    // - Load balances requests across healthy instances (round-robin)
    // - Handles service instances joining/leaving dynamically

    // Make RPC call (same API regardless of connection style)
    let request = Bytes::from("Hello, World!");
    let response = client.sync_call("echo", request, 5000).await?;

    println!("Response: {}", String::from_utf8_lossy(&response));
    Ok(())
}
```

### Server Example - Direct TCP (Style 1)

```rust
use bytes::Bytes;
use std::sync::Arc;
use zus_rs::{RpcServer, prelude::*};

struct EchoService;

#[async_trait]
impl Service for EchoService {
    fn service_name(&self) -> &str {
        "EchoService"
    }

    async fn do_work(
        &self,
        method: &str,
        params: Bytes,
        _context: zus_rs::server::RequestContext,
    ) -> zus_common::Result<Bytes> {
        match method {
            "echo" => Ok(params),
            _ => Err(zus_common::ZusError::MethodNotFound(method.to_string())),
        }
    }
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Start server without ZooServer - clients connect via tcp://host:9527
    let mut server = RpcServer::new("0.0.0.0".to_string(), 9527);
    server.register_service(Arc::new(EchoService));
    server.start().await?;
    Ok(())
}
```

### Server Example - With ZooServer Registration (Style 2)

```rust
use bytes::Bytes;
use std::sync::Arc;
use zus_rs::{RpcServer, prelude::*};
use zus_discovery::ZusZooClient;

struct EchoService;

#[async_trait]
impl Service for EchoService {
    fn service_name(&self) -> &str {
        "EchoService"
    }

    async fn do_work(
        &self,
        method: &str,
        params: Bytes,
        _context: zus_rs::server::RequestContext,
    ) -> zus_common::Result<Bytes> {
        match method {
            "echo" => Ok(params),
            _ => Err(zus_common::ZusError::MethodNotFound(method.to_string())),
        }
    }
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Connect to ZooServer
    let zoo_client = Arc::new(
        ZusZooClient::new(vec!["localhost:9528".to_string()]).await?
    );

    // Start server WITH ZooServer registration
    // Server will automatically register at /zus/services/rust/0.0.0.0:9527
    let mut server = RpcServer::new("0.0.0.0".to_string(), 9527)
        .with_zoo_client(zoo_client);

    server.register_service(Arc::new(EchoService));
    server.start().await?;
    Ok(())
}
```

## Running ZooServer (Standalone)

To use Style 2 (ZooServer-based discovery), you need a running ZooServer instance. ZUS-RS includes a production-ready ZooServer implementation.

### Quick Start

```bash
# Run with default settings (binds to 0.0.0.0:9528)
cargo run --bin zooserver

# Run with a config file
cargo run --bin zooserver -- path/to/config.cfg

# Run with debug logging
RUST_LOG=debug cargo run --bin zooserver
```

### Configuration File

Create a `.cfg` file to customize ZooServer:

```ini
[zusnet]
# Maximum concurrent connections (default: 1000)
maxconnects=1000

# Idle connection timeout in seconds (default: 60)
idleconntimeout=60

# Enable compression (default: true)
COMPRESS=true

# Compression threshold in bytes (default: 4096)
COMPRESS_THRESHSIZE=4096

[zooserver]
# Server listening port (default: 9528)
srvport=9528
```

### Example: Full Setup with ZooServer

```bash
# Terminal 1: Start ZooServer
cargo run --bin zooserver

# Terminal 2: Start your service (registers with ZooServer)
cargo run --bin your-service

# Terminal 3: Run client (discovers service via ZooServer)
cargo run --bin your-client
```

### ZooServer Features

- **Service Discovery**: Services register at paths like `/zus/services/myservice/tcp:host:port`
- **Ephemeral Nodes**: Auto-cleanup when services disconnect
- **Distributed Locking**: Path-based distributed locks
- **Session Management**: Automatic timeout (default: 10s)
- **Health Monitoring**: Clients send periodic heartbeats via `SyncPath`

For more details, see `zooserver/README.md`.

## Feature Flags

Choose the features you need to minimize dependencies:

| Feature | Description | Use Case |
|---------|-------------|----------|
| `default` | Client + Server + Protocol | Full-featured applications |
| `minimal` | Protocol definitions only | Message definitions for FFI |
| `protocol` | Protocol + Codec + Compression | Custom transport layer |
| `client` | RPC client functionality | Client applications |
| `server` | RPC server functionality | Service implementations |
| `full` | Everything | Development and testing |

### Examples

```toml
# Microservice (server only)
[dependencies]
zus-rs = { version = "1.1.4", features = ["server"] }

# Client application
[dependencies]
zus-rs = { version = "1.1.4", features = ["client"] }

# Protocol implementation (custom transport)
[dependencies]
zus-rs = { version = "1.1.4", features = ["protocol"] }

# Minimal (just message definitions)
[dependencies]
zus-rs = { version = "1.1.4", features = ["minimal"] }
```

## Architecture

```text
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              zus-rs (convenience)                β”‚
β”‚  Feature flags: minimal, protocol, client, serverβ”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚              β”‚              β”‚
        ↓              ↓              ↓
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚ client  β”‚   β”‚ server  β”‚   β”‚ protocol β”‚
   β”‚ feature β”‚   β”‚ feature β”‚   β”‚ feature  β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚              β”‚              β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                       ↓
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚  zus-rpc-{client,server}     β”‚
        β”‚  zus-discovery (ZooServer)   β”‚
        β”‚  zus-common (codec/compress) β”‚
        β”‚  zus-proto (protobuf msgs)   β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```

## Module Organization

```rust
use zus_rs::proto;       // Protocol Buffer definitions (always available)
use zus_rs::common;      // Codec and compression (protocol feature)
use zus_rs::discovery;   // ZooServer client (client/server features)
use zus_rs::client;      // RPC client (client feature)
use zus_rs::server;      // RPC server (server feature)

// Or use the prelude for common imports
use zus_rs::prelude::*;
```

## Cross-Language Compatibility

ZUS-RS is wire-compatible with Java and C++ implementations:

- βœ… **Java**: Full compatibility tested with integration tests
- βœ… **C++**: Production-tested compatibility
- βœ… **Protocol**: Same 40-byte RPC header format
- βœ… **Compression**: Same QuickLZ/Snappy algorithms
- βœ… **Validation**: Same CRC16/CRC32 checksums

### Compression Strategy

ZUS-RS implements **params-only compression for requests** to match Java's decoder architecture:

- **Requests**: Method name stays uncompressed, only params data is compressed
- **Responses**: Full body compression
- **Threshold**: 4096 bytes (4KB) default, configurable
- **Algorithms**: QuickLZ Level 1 (default), Snappy fallback

This ensures perfect cross-language compatibility:
```
βœ… Java Client β†’ Rust Server
βœ… Rust Client β†’ Java Server
βœ… C++ Client β†’ Rust Server
βœ… Rust Client β†’ C++ Server
```

## Address Format Reference

### Direct Connection (tcp://)
```
Single endpoint:   tcp://host:port
Multiple endpoints: tcp://host1:port1,host2:port2,host3:port3
```

**Examples:**
- `tcp://localhost:9527`
- `tcp://192.168.1.10:9527`
- `tcp://service1.example.com:9527,service2.example.com:9527`

### ZooServer Discovery (zns://)
```
Format: zns://zooserver1:port1[,zooserver2:port2]/service/path/
```

**Examples:**
- `zns://localhost:9528/zus/services/myservice/`
- `zns://zoo1:2181,zoo2:2181/zus/services/myservice/`
- `zns://10.0.1.1:2181/zus/services/echo/`

**Note:** The service path should end with `/` and correspond to where servers register themselves in ZooServer.

## Performance

- **Throughput**: ~100K requests/sec (localhost, no compression)
- **Latency**: < 1ms p99 (localhost)
- **Compression Ratio**: ~70% reduction (5440 bytes β†’ 477 bytes typical)
- **Memory**: Low overhead with zero-copy where possible

## Examples

See `zus-examples/` for complete examples:

- **Simple Client**: Basic RPC calls (`example-client`)
- **Simple Server**: Service implementation (`example-server`)
- **Telemetry Server**: Server with OpenTelemetry integration (`example-server-telemetry`)
- **ZooServer Discovery**: Service registration and discovery
- **Cross-Language**: Interoperability with Java/C++

## Testing

Run tests for all feature combinations:

```bash
# Test default features
cargo test -p zus-rs

# Test minimal features
cargo test -p zus-rs --no-default-features --features minimal

# Test client only
cargo test -p zus-rs --no-default-features --features client

# Test server only
cargo test -p zus-rs --no-default-features --features server

# Test all features
cargo test -p zus-rs --all-features
```

## Documentation

- [Getting Started Guide]../docs/GETTING_STARTED.md
- [Protocol Specification]../docs/protocol&wireformat.md
- [ZooServer Architecture]../docs/ZOOSERVER_ARCHITECTURE.md
- [Cross-Language Tests]../tests/cross-language/README.md
- [Repository Organization]../docs/REPOSITORY_ORGANIZATION_ANALYSIS.md

## Contributing

Contributions are welcome! Please see [CONTRIBUTING.md](../CONTRIBUTING.md) for guidelines.

## License

Licensed under either of:

- Apache License, Version 2.0 ([LICENSE-APACHE]../LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license ([LICENSE-MIT]../LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

## Credits

Developed by the ZUS Rust Team as a modern, cross-language compatible RPC framework.

**Version**: 1.1.4
**Last Updated**: 2026-01-21
**Status**: Production Ready