#!/usr/bin/env python3 """ Example demonstrating multiple connections per peer support in libp2p. This example shows how to: 1. Configure multiple connections per peer 2. Use different load balancing strategies 3. Access multiple connections through the new API 4. Maintain backward compatibility """ import logging import trio from libp2p import new_swarm from libp2p.network.swarm import ConnectionConfig, RetryConfig # Set up logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) async def example_basic_multiple_connections() -> None: """Example of basic multiple connections per peer usage.""" logger.info("Creating swarm with multiple connections support...") # Create swarm with default configuration swarm = new_swarm() default_connection = ConnectionConfig() logger.info(f"Swarm created with peer ID: {swarm.get_peer_id()}") logger.info( f"Connection config: max_connections_per_peer=" f"{default_connection.max_connections_per_peer}" ) await swarm.close() logger.info("Basic multiple connections example completed") async def example_custom_connection_config() -> None: """Example of custom connection configuration.""" logger.info("Creating swarm with custom connection configuration...") # Custom connection configuration for high-performance scenarios connection_config = ConnectionConfig( max_connections_per_peer=5, # More connections per peer connection_timeout=60.0, # Longer timeout load_balancing_strategy="least_loaded", # Use least loaded strategy ) # Create swarm with custom connection config swarm = new_swarm(connection_config=connection_config) logger.info("Custom connection config applied:") logger.info( f" Max connections per peer: {connection_config.max_connections_per_peer}" ) logger.info(f" Connection timeout: {connection_config.connection_timeout}s") logger.info( f" Load balancing strategy: {connection_config.load_balancing_strategy}" ) await swarm.close() logger.info("Custom connection config example completed") async def example_multiple_connections_api() -> None: """Example of using the new multiple connections API.""" logger.info("Demonstrating multiple connections API...") connection_config = ConnectionConfig( max_connections_per_peer=3, load_balancing_strategy="round_robin" ) swarm = new_swarm(connection_config=connection_config) logger.info("Multiple connections API features:") logger.info(" - dial_peer() returns list[INetConn]") logger.info(" - get_connections(peer_id) returns list[INetConn]") logger.info(" - get_connections_map() returns dict[ID, list[INetConn]]") logger.info( " - get_connection(peer_id) returns INetConn | None (backward compatibility)" ) await swarm.close() logger.info("Multiple connections API example completed") async def example_backward_compatibility() -> None: """Example of backward compatibility features.""" logger.info("Demonstrating backward compatibility...") swarm = new_swarm() logger.info("Backward compatibility features:") logger.info(" - connections_legacy property provides 1:1 mapping") logger.info(" - get_connection() method for single connection access") logger.info(" - Existing code continues to work") await swarm.close() logger.info("Backward compatibility example completed") async def example_production_ready_config() -> None: """Example of production-ready configuration.""" logger.info("Creating swarm with production-ready configuration...") # Production-ready retry configuration retry_config = RetryConfig( max_retries=3, # Reasonable retry limit initial_delay=0.1, # Quick initial retry max_delay=30.0, # Cap exponential backoff backoff_multiplier=2.0, # Standard exponential backoff jitter_factor=0.1, # Small jitter to prevent thundering herd ) # Production-ready connection configuration connection_config = ConnectionConfig( max_connections_per_peer=3, # Balance between performance and resource usage connection_timeout=30.0, # Reasonable timeout load_balancing_strategy="round_robin", # Simple, predictable strategy ) # Create swarm with production config swarm = new_swarm(retry_config=retry_config, connection_config=connection_config) logger.info("Production-ready configuration applied:") logger.info( f" Retry: {retry_config.max_retries} retries, " f"{retry_config.max_delay}s max delay" ) logger.info(f" Connections: {connection_config.max_connections_per_peer} per peer") logger.info(f" Load balancing: {connection_config.load_balancing_strategy}") await swarm.close() logger.info("Production-ready configuration example completed") async def main() -> None: """Run all examples.""" logger.info("Multiple Connections Per Peer Examples") logger.info("=" * 50) try: await example_basic_multiple_connections() logger.info("-" * 30) await example_custom_connection_config() logger.info("-" * 30) await example_multiple_connections_api() logger.info("-" * 30) await example_backward_compatibility() logger.info("-" * 30) await example_production_ready_config() logger.info("-" * 30) logger.info("All examples completed successfully!") except Exception as e: logger.error(f"Example failed: {e}") raise if __name__ == "__main__": trio.run(main)