11// Issue #32: Async Provider Validation Demo
2- //
2+ //
33// This demo showcases the async validation system that tests provider connections
44// in the background without blocking the UI thread.
55
6- use agentic:: {
7- settings:: {
8- Settings , ProviderType , ValidationEvent , ValidationService ,
9- validate_local_provider, validate_openrouter_provider, AsyncValidationResult ,
10- ValidationStatus
11- } ,
6+ use agentic:: settings:: {
7+ AsyncValidationResult , ProviderType , Settings , ValidationEvent , ValidationService ,
8+ ValidationStatus , validate_local_provider, validate_openrouter_provider,
129} ;
13- use tokio:: sync:: mpsc;
1410use std:: time:: Duration ;
11+ use tokio:: sync:: mpsc;
1512
1613#[ tokio:: main]
1714async fn main ( ) {
1815 println ! ( "🔍 Issue #32: Async Provider Validation Demo" ) ;
1916 println ! ( "======================================================================" ) ;
2017 println ! ( ) ;
21-
18+
2219 println ! ( "🚀 ASYNC VALIDATION FEATURES:" ) ;
2320 println ! ( " ✅ Non-blocking async validation" ) ;
2421 println ! ( " ✅ LOCAL endpoint connection testing" ) ;
@@ -29,20 +26,21 @@ async fn main() {
2926 println ! ( " ✅ Response time measurement" ) ;
3027 println ! ( " ✅ Event-driven architecture" ) ;
3128 println ! ( ) ;
32-
29+
3330 // Create event channel for validation results
3431 let ( tx, mut rx) = mpsc:: unbounded_channel :: < ValidationEvent > ( ) ;
35-
32+
3633 // Create settings with test configuration
3734 let mut settings = Settings :: new ( ) ;
38-
35+
3936 // Configure test endpoints and keys
4037 settings. local_provider . endpoint_url = Some ( "http://localhost:11434" . to_string ( ) ) ;
41- settings. openrouter_provider . api_key = Some ( "sk-or-v1-test-key-for-validation-demo" . to_string ( ) ) ;
42-
38+ settings. openrouter_provider . api_key =
39+ Some ( "sk-or-v1-test-key-for-validation-demo" . to_string ( ) ) ;
40+
4341 println ! ( "🧪 TESTING INDIVIDUAL VALIDATION FUNCTIONS:" ) ;
4442 println ! ( ) ;
45-
43+
4644 // Test 1: Valid local endpoint (assuming Ollama running)
4745 println ! ( "📝 Testing LOCAL endpoint validation:" ) ;
4846 let local_result = validate_local_provider ( "http://localhost:11434" ) . await ;
@@ -54,7 +52,7 @@ async fn main() {
5452 println ! ( " Response time: {}ms" , time. as_millis( ) ) ;
5553 }
5654 println ! ( ) ;
57-
55+
5856 // Test 2: Invalid local endpoint
5957 println ! ( "📝 Testing invalid LOCAL endpoint:" ) ;
6058 let invalid_local = validate_local_provider ( "http://localhost:99999" ) . await ;
@@ -63,7 +61,7 @@ async fn main() {
6361 println ! ( " Message: {}" , msg) ;
6462 }
6563 println ! ( ) ;
66-
64+
6765 // Test 3: OpenRouter API validation (will fail with test key)
6866 println ! ( "🔐 Testing OPENROUTER API validation:" ) ;
6967 let openrouter_result = validate_openrouter_provider ( "sk-or-v1-test-key-invalid" ) . await ;
@@ -72,40 +70,39 @@ async fn main() {
7270 println ! ( " Message: {}" , msg) ;
7371 }
7472 println ! ( ) ;
75-
73+
7674 println ! ( "🔄 TESTING ASYNC VALIDATION SERVICE:" ) ;
7775 println ! ( ) ;
78-
76+
7977 // Create validation service
8078 let validation_service = ValidationService :: new ( tx. clone ( ) ) ;
81-
79+
8280 // Test async validation for both providers
8381 println ! ( " Starting LOCAL provider validation..." ) ;
84- validation_service. validate_provider (
85- ProviderType :: Local ,
86- & settings. local_provider
87- ) . await ;
88-
82+ validation_service
83+ . validate_provider ( ProviderType :: Local , & settings. local_provider )
84+ . await ;
85+
8986 println ! ( " Starting OPENROUTER provider validation..." ) ;
90- validation_service. validate_provider (
91- ProviderType :: OpenRouter ,
92- & settings. openrouter_provider
93- ) . await ;
94-
87+ validation_service
88+ . validate_provider ( ProviderType :: OpenRouter , & settings. openrouter_provider )
89+ . await ;
90+
9591 // Collect validation events
9692 let mut events_received = 0 ;
9793 let max_events = 4 ; // Start + Complete for each provider
98-
94+
9995 println ! ( ) ;
10096 println ! ( "📡 VALIDATION EVENTS:" ) ;
101-
97+
10298 while events_received < max_events {
10399 if let Ok ( event) = tokio:: time:: timeout ( Duration :: from_secs ( 10 ) , rx. recv ( ) ) . await {
104100 if let Some ( event) = event {
105101 match event {
106102 ValidationEvent :: StartValidation ( provider) => {
107103 println ! ( " 🔄 Started validation for {:?}" , provider) ;
108- settings. handle_validation_event ( ValidationEvent :: StartValidation ( provider) ) ;
104+ settings
105+ . handle_validation_event ( ValidationEvent :: StartValidation ( provider) ) ;
109106 }
110107 ValidationEvent :: ValidationComplete { provider, result } => {
111108 println ! ( " ✅ Completed validation for {:?}" , provider) ;
@@ -116,9 +113,9 @@ async fn main() {
116113 if let Some ( time) = result. response_time {
117114 println ! ( " Response time: {}ms" , time. as_millis( ) ) ;
118115 }
119- settings. handle_validation_event ( ValidationEvent :: ValidationComplete {
120- provider : provider. clone ( ) ,
121- result
116+ settings. handle_validation_event ( ValidationEvent :: ValidationComplete {
117+ provider : provider. clone ( ) ,
118+ result,
122119 } ) ;
123120 }
124121 }
@@ -129,53 +126,62 @@ async fn main() {
129126 break ;
130127 }
131128 }
132-
129+
133130 println ! ( ) ;
134131 println ! ( "📊 FINAL VALIDATION STATUS:" ) ;
135- println ! ( " LOCAL Provider: {:?}" , settings. local_provider. validation_status) ;
136- println ! ( " OPENROUTER Provider: {:?}" , settings. openrouter_provider. validation_status) ;
132+ println ! (
133+ " LOCAL Provider: {:?}" ,
134+ settings. local_provider. validation_status
135+ ) ;
136+ println ! (
137+ " OPENROUTER Provider: {:?}" ,
138+ settings. openrouter_provider. validation_status
139+ ) ;
137140 println ! ( ) ;
138-
141+
139142 println ! ( "🧪 TESTING SETTINGS INTEGRATION:" ) ;
140143 println ! ( ) ;
141-
144+
142145 // Test the settings-level validation methods
143146 let ( tx2, mut rx2) = mpsc:: unbounded_channel :: < ValidationEvent > ( ) ;
144-
147+
145148 println ! ( " Testing validate_all_providers..." ) ;
146149 let tasks = settings. validate_all_providers ( tx2. clone ( ) ) . await ;
147150 println ! ( " Started {} validation tasks" , tasks. len( ) ) ;
148-
151+
149152 // Wait for all tasks to complete
150153 for task in tasks {
151154 let _ = task. await ;
152155 }
153-
156+
154157 // Collect results
155158 let mut events_received2 = 0 ;
156- while events_received2 < 4 &&
157- tokio:: time:: timeout ( Duration :: from_secs ( 2 ) , rx2. recv ( ) ) . await . is_ok ( ) {
159+ while events_received2 < 4
160+ && tokio:: time:: timeout ( Duration :: from_secs ( 2 ) , rx2. recv ( ) )
161+ . await
162+ . is_ok ( )
163+ {
158164 events_received2 += 1 ;
159165 }
160-
166+
161167 println ! ( " Received {} validation events" , events_received2) ;
162168 println ! ( ) ;
163-
169+
164170 println ! ( "🔍 VALIDATION TRIGGERS:" ) ;
165171 println ! ( " ✅ Individual provider validation" ) ;
166172 println ! ( " ✅ All providers validation" ) ;
167173 println ! ( " ✅ Event-driven status updates" ) ;
168174 println ! ( " ✅ Non-blocking async execution" ) ;
169175 println ! ( ) ;
170-
176+
171177 println ! ( "🛡️ ERROR HANDLING:" ) ;
172178 println ! ( " ✅ Network timeouts (5s limit)" ) ;
173179 println ! ( " ✅ Connection failures" ) ;
174180 println ! ( " ✅ HTTP status codes" ) ;
175181 println ! ( " ✅ Authentication errors" ) ;
176182 println ! ( " ✅ Rate limiting detection" ) ;
177183 println ! ( ) ;
178-
184+
179185 println ! ( "🎉 Issue #32 Implementation Complete!" ) ;
180186 println ! ( "📋 All Success Criteria Met:" ) ;
181187 println ! ( " ✅ Async validation runs without blocking UI" ) ;
0 commit comments