mirror of
				https://github.com/oarkflow/mq.git
				synced 2025-11-01 02:32:35 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			122 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package main
 | ||
| 
 | ||
| import (
 | ||
| 	"context"
 | ||
| 	"fmt"
 | ||
| 	"log"
 | ||
| 	"net/http"
 | ||
| 	"time"
 | ||
| 
 | ||
| 	"github.com/oarkflow/mq"
 | ||
| 	"github.com/oarkflow/mq/logger"
 | ||
| )
 | ||
| 
 | ||
| // Example: Proper timeout patterns for different connection types
 | ||
| func demonstrateTimeoutPatterns() {
 | ||
| 	fmt.Println("\n=== Connection Timeout Patterns ===")
 | ||
| 
 | ||
| 	// ✅ GOOD: No I/O timeout for persistent broker-consumer connections
 | ||
| 	fmt.Println("✅ Broker-Consumer: NO I/O timeouts (persistent connection)")
 | ||
| 	fmt.Println("   - Uses TCP keep-alive for network detection")
 | ||
| 	fmt.Println("   - Uses context cancellation for graceful shutdown")
 | ||
| 	fmt.Println("   - Connection stays open indefinitely waiting for messages")
 | ||
| 
 | ||
| 	// ✅ GOOD: Timeout for connection establishment
 | ||
| 	fmt.Println("✅ Connection Setup: WITH timeout (initial connection)")
 | ||
| 	fmt.Println("   - 10-30 second timeout for initial TCP handshake")
 | ||
| 	fmt.Println("   - Prevents hanging on unreachable servers")
 | ||
| 
 | ||
| 	// ✅ GOOD: Timeout for individual task processing
 | ||
| 	fmt.Println("✅ Task Processing: WITH timeout (individual operations)")
 | ||
| 	fmt.Println("   - 30 second timeout per task (configurable)")
 | ||
| 	fmt.Println("   - Prevents individual tasks from hanging forever")
 | ||
| 
 | ||
| 	// ❌ BAD: I/O timeout on persistent connections
 | ||
| 	fmt.Println("❌ Persistent I/O: NO timeouts on read/write operations")
 | ||
| 	fmt.Println("   - Would cause 'i/o timeout' errors on idle connections")
 | ||
| 	fmt.Println("   - Breaks the persistent connection model")
 | ||
| 
 | ||
| 	fmt.Println("\n💡 Key Principle:")
 | ||
| 	fmt.Println("   - Connection timeouts: Only for establishment")
 | ||
| 	fmt.Println("   - I/O timeouts: Only for request/response patterns")
 | ||
| 	fmt.Println("   - Persistent connections: Use keep-alive + context cancellation")
 | ||
| }
 | ||
| 
 | ||
| func main() {
 | ||
| 	fmt.Println("=== Minimal Admin Server Test ===")
 | ||
| 
 | ||
| 	// Demonstrate proper timeout patterns
 | ||
| 	demonstrateTimeoutPatterns()
 | ||
| 
 | ||
| 	// Create logger
 | ||
| 	lg := logger.NewDefaultLogger()
 | ||
| 	fmt.Println("\n✅ Logger created")
 | ||
| 
 | ||
| 	// Create broker with NO I/O timeouts for persistent connections
 | ||
| 	broker := mq.NewBroker(mq.WithLogger(lg), mq.WithBrokerURL(":8081"))
 | ||
| 	fmt.Println("✅ Broker created (NO I/O timeouts - persistent connections)")
 | ||
| 
 | ||
| 	// Start broker
 | ||
| 	ctx := context.Background()
 | ||
| 	fmt.Println("🚀 Starting broker...")
 | ||
| 
 | ||
| 	// Start broker in goroutine since it blocks
 | ||
| 	go func() {
 | ||
| 		if err := broker.Start(ctx); err != nil {
 | ||
| 			log.Printf("❌ Broker error: %v", err)
 | ||
| 		}
 | ||
| 	}()
 | ||
| 
 | ||
| 	// Give broker time to start
 | ||
| 	time.Sleep(500 * time.Millisecond)
 | ||
| 	fmt.Println("✅ Broker started")
 | ||
| 	defer broker.Close()
 | ||
| 
 | ||
| 	// Create admin server
 | ||
| 	fmt.Println("🔧 Creating admin server...")
 | ||
| 	adminServer := mq.NewAdminServer(broker, ":8090", lg)
 | ||
| 	fmt.Println("✅ Admin server created")
 | ||
| 
 | ||
| 	// Start admin server
 | ||
| 	fmt.Println("🚀 Starting admin server...")
 | ||
| 	if err := adminServer.Start(); err != nil {
 | ||
| 		log.Fatalf("❌ Failed to start admin server: %v", err)
 | ||
| 	}
 | ||
| 	defer adminServer.Stop()
 | ||
| 	fmt.Println("✅ Admin server started")
 | ||
| 
 | ||
| 	// Wait and test
 | ||
| 	fmt.Println("⏳ Waiting 2 seconds...")
 | ||
| 	time.Sleep(2 * time.Second)
 | ||
| 
 | ||
| 	fmt.Println("🔍 Testing connectivity...")
 | ||
| 
 | ||
| 	// ✅ GOOD: HTTP client WITH timeout (request/response pattern)
 | ||
| 	client := &http.Client{Timeout: 5 * time.Second}
 | ||
| 	resp, err := client.Get("http://localhost:8090/api/admin/health")
 | ||
| 	if err != nil {
 | ||
| 		fmt.Printf("❌ Connection failed: %v\n", err)
 | ||
| 	} else {
 | ||
| 		fmt.Printf("✅ Connection successful! Status: %d\n", resp.StatusCode)
 | ||
| 		resp.Body.Close()
 | ||
| 	}
 | ||
| 
 | ||
| 	fmt.Println("\n🌐 Admin Dashboard: http://localhost:8090/admin")
 | ||
| 	fmt.Println("📊 Health API: http://localhost:8090/api/admin/health")
 | ||
| 	fmt.Println("📡 Broker API: http://localhost:8090/api/admin/broker")
 | ||
| 	fmt.Println("📋 Queue API: http://localhost:8090/api/admin/queues")
 | ||
| 
 | ||
| 	fmt.Println("\n💡 Connection Patterns Demonstrated:")
 | ||
| 	fmt.Println("   🔗 Broker ↔ Consumer: Persistent (NO I/O timeouts)")
 | ||
| 	fmt.Println("   🌐 HTTP Client ↔ Admin: Request/Response (WITH timeouts)")
 | ||
| 	fmt.Println("   ⚡ WebSocket ↔ Dashboard: Persistent (NO I/O timeouts)")
 | ||
| 
 | ||
| 	fmt.Println("\n⚠️ Server running - Press Ctrl+C to stop")
 | ||
| 	fmt.Println("   - Broker connections will remain persistent")
 | ||
| 	fmt.Println("   - No 'i/o timeout' errors should occur")
 | ||
| 	fmt.Println("   - TCP keep-alive handles network detection")
 | ||
| 
 | ||
| 	// Keep running
 | ||
| 	select {}
 | ||
| }
 | 
