lightstreamer-client 0.1.12

A Rust client for Lightstreamer, designed to facilitate real-time communication with Lightstreamer servers.
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
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
# AI Agent Guidelines for Lightstreamer Rust Client SDK

## Project Overview

This is a **Rust client SDK** for Lightstreamer servers implementing the **TLCP (Text-based Live Connections Protocol)**. The project provides real-time streaming capabilities focused on WebSocket-based connections, subscriptions management, and item update handling.

### Project Characteristics
- **Language**: Rust (Edition 2021)
- **Primary Use Case**: Real-time data streaming from Lightstreamer servers
- **Architecture**: Async/await pattern using Tokio runtime
- **Protocol**: TLCP v2.4.0 over WebSocket
- **Current Focus**: MERGE subscription mode with WebSocket streaming transport
- **Target Application**: Built specifically to support the [ig_trading_api]https://github.com/daniloaz/ig_trading_api project

### License
GPL-3.0-only - All code contributions must respect this license.

---

## Core Principles and Mandatory Rules

### 1. Communication Language
- **ALWAYS respond to users in English**, regardless of the user's input language
- **ALL code comments MUST be written in English**
- Keep existing comment format and style when modifying code
- Enhance comments for better quality and understanding when appropriate

### 2. Autonomous Development
- **Make programming decisions autonomously** without requesting confirmation at every step
- Choose the most effective resolution following best practices
- Ensure code efficiency and maintainability
- Only ask for clarification when requirements are genuinely ambiguous

### 3. Documentation Synchronization
- **ALWAYS update `.md` documentation files** to reflect code changes
- Documentation must represent the **current state**, not a changelog
- Keep documentation accurate, clear, and synchronized with implementation
- Document public APIs, modules, and key architectural decisions

### 4. Code Quality Standards
- Follow Rust best practices and idioms
- Respect existing code patterns in the project
- Write clear, self-documenting code
- Add meaningful comments for complex logic
- Ensure proper error handling throughout

---

## Technical Architecture

### Project Structure

```
lightstreamer-client/
├── src/
│   ├── lib.rs                      # Public API exports
│   ├── ls_client.rs                # Main client implementation (Facade)
│   ├── subscription.rs             # Subscription management
│   ├── item_update.rs              # Real-time update data structure
│   ├── connection_details.rs       # Server connection configuration
│   ├── connection_options.rs       # Connection behavior options
│   ├── client_listener.rs          # Client event callbacks (trait)
│   ├── subscription_listener.rs    # Subscription event callbacks (trait)
│   ├── client_message_listener.rs  # Message event callbacks (trait)
│   ├── error.rs                    # Custom error types
│   ├── proxy.rs                    # Proxy configuration (future)
│   ├── util.rs                     # Utility functions
│   └── main.rs                     # Example/demo usage
├── Cargo.toml                      # Dependencies and metadata
├── README.md                       # User-facing documentation
├── LICENSE                         # GPL-3.0 license
└── AGENTS.md                       # This file
```

### Key Dependencies

```toml
# Async Runtime
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }

# WebSocket Communication
tokio-tungstenite = { version = "0", features = ["native-tls"] }

# HTTP Client
reqwest = { version = "0", features = ["json", "stream"] }

# Serialization
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_urlencoded = "0"

# Async Utilities
futures = "0"
futures-util = "0"

# Logging
tracing = "0.1.40"
tracing-subscriber = "0.3.18"

# Other
url = "2"
json-patch = "1"
cookie = { version = "0", features = ["percent-encode"] }
signal-hook = "0"
colored = "2"
```

---

## Architectural Patterns

### 1. Facade Pattern
The `LightstreamerClient` serves as a facade for all operations:
- Connection lifecycle management
- Subscription handling
- Message sending
- Event listener registration

### 2. Listener/Observer Pattern
Event-driven architecture using trait-based listeners:
- `ClientListener`: Connection and session events
- `SubscriptionListener`: Subscription lifecycle and updates
- `ClientMessageListener`: Message delivery notifications

### 3. Async/Await with Tokio
- All I/O operations are non-blocking
- Uses `tokio::select!` for concurrent event handling
- Channel-based message passing for subscription operations

### 4. Builder Pattern
Configuration objects (`ConnectionDetails`, `ConnectionOptions`) use builder-like setters.

---

## Implementation Guidelines

### Connection Handling

#### WebSocket Communication
- **Only WebSocket streaming transport is currently supported**
- HTTP polling/streaming modes are planned but not implemented
- Connection uses standard WebSocket upgrade with custom TLCP headers
- Messages are text-based, CRLF-delimited

#### Connection Flow
1. WebSocket handshake with TLCP protocol headers
2. Send `wsok` message to initiate
3. Receive `wsok` confirmation from server
4. Send `create_session` with credentials and adapter set
5. Receive `conok` with session ID
6. Subscribe to items via `control` messages
7. Process real-time updates via message loop

### Subscription Management

#### Subscription Lifecycle
1. Create `Subscription` with mode, items, and fields
2. Call `LightstreamerClient::subscribe()` (non-blocking)
3. Client sends subscription request when session is active
4. Receive `subok` confirmation
5. Process `u` (update) messages
6. Unsubscribe via `LightstreamerClient::unsubscribe()`
7. Receive `unsub` confirmation

#### Current Limitations
- Only **MERGE mode** is fully implemented
- DISTINCT, RAW, and COMMAND modes are not supported yet
- Snapshot handling is implemented for MERGE mode

### Message Protocol (TLCP)

#### Key Message Types
- `wsok`: WebSocket connection confirmation
- `create_session`: Session creation request
- `conok`: Session creation confirmation
- `control`: Subscription/unsubscription commands
- `subok`: Subscription confirmation
- `unsub`: Unsubscription confirmation
- `u`: Item update (data)
- `reqok`: Request acknowledged
- `conerr`, `reqerr`: Error messages
- `probe`: Keep-alive probe

#### Update Message Format
```
u,<subscription_id>,<item_index>,<field_values>
```

Field values are pipe-separated:
- Empty value `""`: Unchanged field
- `#` or `$`: Null/empty field
- `^<number>`: Skip N unchanged fields
- `^P<json_patch>`: Apply JSON Patch
- `^T<tlcp_diff>`: Apply TLCP diff (not implemented)
- Regular value: URL-encoded field value

---

## Error Handling

### Custom Exceptions
Define custom error types in `error.rs`:
```rust
#[derive(Debug)]
pub struct IllegalStateException {
    message: String,
}
```

### Error Propagation
- Use `Result<T, Box<dyn Error + Send + Sync>>` for async operations
- Use `Result<T, Box<dyn Error>>` for sync operations
- Provide descriptive error messages
- Log errors appropriately before propagation

### Error Scenarios
- Connection failures
- Invalid configuration
- Protocol violations
- Subscription errors
- Network timeouts

---

## Logging Strategy

### Dual Logging Support
The client supports two logging mechanisms:

1. **Standard Logs** (`LogType::StdLogs`): Direct to stdout
2. **Tracing Logs** (`LogType::TracingLogs`): Via `tracing` crate

### Log Levels
- `ERROR`: Critical failures, protocol errors
- `WARN`: Non-critical issues, unexpected states
- `INFO`: Important events (connection, subscription confirmations)
- `DEBUG`: Detailed protocol messages, state changes
- `TRACE`: Low-level details (rarely used)

### Logging Categories (Future)
Plan to align with official Lightstreamer categories:
- `lightstreamer.stream`: Socket operations
- `lightstreamer.protocol`: TLCP protocol messages
- `lightstreamer.session`: Session lifecycle
- `lightstreamer.subscriptions`: Subscription events
- `lightstreamer.actions`: API calls and settings

---

## Code Style and Conventions

### Naming Conventions
- **Types**: `PascalCase` (e.g., `LightstreamerClient`, `ItemUpdate`)
- **Functions/Methods**: `snake_case` (e.g., `connect()`, `get_status()`)
- **Constants**: `SCREAMING_SNAKE_CASE` (e.g., `LIB_VERSION`, `TLCP_VERSION`)
- **Private fields**: Prefix with `_` if unused (e.g., `_session_id`)

### Documentation Comments
```rust
/// Brief description of the function/struct.
///
/// More detailed explanation if needed. Describe behavior,
/// use cases, and important notes.
///
/// # Parameters
///
/// * `param_name`: Description of parameter.
///
/// # Returns
///
/// Description of return value.
///
/// # Raises/Errors
///
/// Description of error conditions.
///
/// # Example
///
/// ```rust
/// // Example usage
/// ```
///
/// See also `related_function()`
```

### Error Messages
- Be specific and actionable
- Include context (what operation failed, why)
- Use proper capitalization and punctuation

### Async Functions
- Mark with `async` keyword
- Use `.await` for async operations
- Prefer `tokio::spawn` for background tasks
- Use `tokio::select!` for concurrent operations

---

## Testing Guidelines

### Test Organization
```rust
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_feature_name() {
        // Arrange
        // Act
        // Assert
    }

    #[tokio::test]
    async fn test_async_feature() {
        // Async test
    }
}
```

### Testing Priorities
1. **Connection logic**: WebSocket handshake, session creation
2. **Message parsing**: TLCP protocol messages
3. **Update handling**: Field value decoding, snapshot detection
4. **Subscription lifecycle**: Subscribe, update, unsubscribe
5. **Error handling**: Invalid states, protocol errors

### Mocking Strategy
- Mock WebSocket connections for unit tests
- Use test servers for integration tests
- Mock listener callbacks to verify event notifications

---

## Common Development Patterns

### Adding a New Feature

1. **Update the API**: Modify relevant structs/traits in `lib.rs`
2. **Implement logic**: Add implementation in appropriate module
3. **Add error handling**: Define new error types if needed
4. **Update documentation**: Sync README.md and inline docs
5. **Add tests**: Unit tests for the new feature
6. **Update examples**: If it affects usage, update `main.rs`

### Adding a New Subscription Mode

1. Extend `SubscriptionMode` enum in `subscription.rs`
2. Update `get_subscription_params()` in `ls_client.rs`
3. Modify update handling logic in the main message loop
4. Add snapshot detection logic for the new mode
5. Update tests and documentation

### Adding a New Transport

1. Extend `Transport` enum in `ls_client.rs`
2. Implement connection logic in `connect()` method
3. Handle transport-specific message formats
4. Update error handling for transport failures
5. Test with mock servers

---

## Important Constraints

### Protocol Limitations
- **TLCP v2.4.0**: Stick to this protocol version
- **WebSocket Only**: HTTP transports are not yet supported
- **MERGE Mode**: Primary focus; other modes are partial

### State Management
- Subscriptions persist across reconnections
- No session recovery mechanism yet implemented
- Shutdown signal handling via `Arc<Notify>`

### Thread Safety
- `LightstreamerClient` is **NOT** `Send` or `Sync` by default
- Listener callbacks execute in the event loop thread
- Keep listener logic fast and non-blocking
- Delegate heavy work to separate tasks

### Performance Considerations
- Minimize allocations in the hot path (update processing)
- Use `HashMap` for efficient field lookups
- Batch subscription requests when possible
- Consider message throughput in buffer sizing

---

## Feature Roadmap

### Implemented
- ✅ WebSocket streaming transport
- ✅ MERGE subscription mode
- ✅ Snapshot handling
- ✅ Real-time item updates
- ✅ Event listeners (Client, Subscription)
- ✅ Connection lifecycle management
- ✅ JSON Patch support (field diffs)

### Planned/Partial
- ⚠️ HTTP streaming transport
- ⚠️ HTTP/WS polling transports
- ⚠️ DISTINCT subscription mode
- ⚠️ RAW subscription mode
- ⚠️ COMMAND subscription mode
- ⚠️ TLCP-diff support
- ⚠️ Message sending (partial implementation)
- ⚠️ Cookie management
- ⚠️ Proxy support
- ⚠️ Session recovery

### Not Implemented
- ❌ Full client message handling
- ❌ Second-level subscriptions
- ❌ Custom logger provider
- ❌ SSL/TLS configuration
- ❌ Listener removal mechanism

---

## Git and Version Control

### Commit Messages
- Use clear, descriptive commit messages
- Start with a verb (Add, Fix, Update, Refactor, etc.)
- Reference issues when applicable

### Branching
- `main`: Stable, production-ready code
- Feature branches: `feature/description`
- Bug fixes: `fix/description`

### Version Numbering
Follow semantic versioning (SEMVER):
- MAJOR: Breaking API changes
- MINOR: New features, backward compatible
- PATCH: Bug fixes, backward compatible

Current version: **0.1.11** (see `Cargo.toml`)

---

## Working with This Project

### Before Making Changes
1. Read the relevant module documentation
2. Understand the TLCP protocol section involved
3. Check for related TODOs or `unimplemented!()` markers
4. Review existing patterns in similar code

### When Adding Code
1. Follow existing code style and patterns
2. Add comprehensive error handling
3. Write inline documentation for public APIs
4. Update README.md if user-facing changes
5. Add or update tests
6. Ensure `cargo build` succeeds
7. Run `cargo test` to verify tests pass
8. Run `cargo clippy` for linting
9. Format code with `cargo fmt`

### When Modifying Code
1. Preserve backward compatibility when possible
2. Update all related documentation
3. Check for side effects in dependent code
4. Update error messages if logic changes
5. Verify tests still pass

### When Removing Code
1. Ensure no public API is broken
2. Remove related tests
3. Update documentation
4. Check for orphaned imports or dependencies

---

## Debugging Tips

### Common Issues

#### Connection Failures
- Check server address format (http:// or https://)
- Verify adapter set name is correct
- Confirm credentials if authentication is required
- Check network connectivity and firewalls

#### Subscription Not Receiving Updates
- Verify item names match server configuration
- Check field names are correct
- Ensure subscription mode is MERGE
- Look for `subok` confirmation in logs

#### Message Parsing Errors
- Enable DEBUG logging to see raw messages
- Check for protocol version mismatches
- Verify URL encoding/decoding

### Logging for Debugging
```rust
client.set_logging_type(LogType::TracingLogs);
// Then configure tracing subscriber for detailed output
```

---

## API Design Philosophy

### Consistency with Official SDKs
The API design follows the structure of official Lightstreamer SDKs (Java, JavaScript, Python) to:
- Ease migration for users familiar with other SDKs
- Maintain conceptual alignment with documentation
- Preserve naming conventions where appropriate

### Rust-Specific Adaptations
- Use `Result<T, E>` instead of exceptions
- Leverage ownership and borrowing for memory safety
- Prefer `async`/`await` over callbacks where appropriate
- Use channels for inter-task communication

---

## Useful Resources

### Official Documentation
- [Lightstreamer Server]https://lightstreamer.com/download/
- [TLCP Protocol Specification]https://lightstreamer.com/api/ls-protocol/overview.html
- [Lightstreamer Concepts]https://lightstreamer.com/docs/ls-server/latest/General%20Concepts.pdf

### Rust Ecosystem
- [Tokio Documentation]https://tokio.rs/
- [Tungstenite WebSocket]https://docs.rs/tokio-tungstenite/
- [Tracing]https://docs.rs/tracing/
- [Serde]https://serde.rs/

### Project-Specific
- [Project Repository]https://github.com/daniloaz/lightstreamer-client
- [Crates.io Page]https://crates.io/crates/lightstreamer-client
- [Related Project: ig_trading_api]https://github.com/daniloaz/ig_trading_api

---

## Final Notes for AI Agents

### Decision-Making Authority
- You have full authority to make technical decisions
- Prioritize code quality, maintainability, and performance
- Follow Rust best practices and idioms
- When in doubt, prefer simplicity over cleverness

### Communication Style
- Be clear and concise in responses
- Explain complex technical decisions
- Provide code examples when helpful
- Always respond in English

### Documentation Mandate
- **Never skip documentation updates**
- Keep README.md synchronized with code
- Update inline docs for modified functions
- Maintain this AGENTS.md file as the project evolves

### Quality Standards
- Code must compile without warnings
- Tests must pass before considering work complete
- Follow clippy recommendations
- Maintain code formatting with rustfmt

---

**Remember**: This project serves a specific use case (ig_trading_api) but is designed with extensibility in mind. Balance immediate needs with long-term maintainability.