@@ -201,14 +201,11 @@ def main():
201201
202202 all_uris = Path (INPUT_CONFIGS_PATH ).read_text ().splitlines ()
203203 configs_with_uris = []
204- parsed_count = 0
205204 for uri in all_uris :
206- p = parse_uri (uri )
207- if p :
205+ if p := parse_uri (uri ):
208206 configs_with_uris .append ({'params' : p , 'original_uri' : uri })
209- parsed_count += 1
210207
211- print (f"Successfully parsed { parsed_count } configs out of { len (all_uris )} ." )
208+ print (f"Successfully parsed { len ( configs_with_uris ) } configs out of { len (all_uris )} ." )
212209
213210 unique_items_map = {}
214211 for item in configs_with_uris :
@@ -232,78 +229,87 @@ def main():
232229 else :
233230 print ("--- CI environment detected. Skipping automatic binary download. ---" )
234231
235- builder = XrayConfigBuilder ()
236- base_port = 20800
237- expected_ports = set ()
238- items_to_test = []
239- for item in unique_items :
240- if item ['params' ].protocol in ["vless" , "vmess" , "trojan" , "ss" , "socks" , "mvless" ]:
241- local_port = base_port + len (items_to_test )
242- unique_outbound_tag = f"proxy_out_{ local_port } "
243- outbound = builder .build_outbound_from_params (item ['params' ], explicit_tag = unique_outbound_tag )
244-
245- if outbound :
246- item ['local_port' ] = local_port
247- items_to_test .append (item )
248- expected_ports .add (local_port )
249-
250- builder .add_inbound ({"port" : local_port , "listen" : "127.0.0.1" , "protocol" : "socks" , "tag" : f"inbound-{ local_port } " })
251- builder .add_outbound (outbound )
252- builder .config ["routing" ]["rules" ].append ({"type" : "field" , "inboundTag" : [f"inbound-{ local_port } " ], "outboundTag" : unique_outbound_tag })
253-
254- if not items_to_test :
255- print ("No Xray-compatible configurations found to test." )
256- return
257-
258232 final_uris_to_write = []
259- try :
260- with XrayCore (vendor_path = str (VENDOR_PATH ), config_builder = builder , debug_mode = True ) as xray :
261- time .sleep (1 )
262- if not xray .is_running ():
263- raise RuntimeError ("Xray process failed to start. The config might still have issues." )
233+ BATCH_SIZE = 50
234+ base_port_start = 20800
235+
236+ for i in range (0 , len (unique_items ), BATCH_SIZE ):
237+ batch_items = unique_items [i :i + BATCH_SIZE ]
238+ print (f"\n --- Processing Batch { i // BATCH_SIZE + 1 } ({ len (batch_items )} configs) ---" )
239+
240+ builder = XrayConfigBuilder ()
241+ items_to_test_in_batch = []
242+ expected_ports = set ()
264243
265- print (f"\n --- Xray is running with { len (items_to_test )} proxies. Waiting for ports... ---" )
244+ for idx , item in enumerate (batch_items ):
245+ if item ['params' ].protocol in ["vless" , "vmess" , "trojan" , "ss" , "socks" , "mvless" ]:
246+ local_port = base_port_start + idx
247+ unique_outbound_tag = f"proxy_out_{ local_port } "
248+ outbound = builder .build_outbound_from_params (item ['params' ], explicit_tag = unique_outbound_tag )
266249
267- ready_ports = set ()
268- for _ in range (40 ):
250+ if outbound :
251+ item ['local_port' ] = local_port
252+ items_to_test_in_batch .append (item )
253+ expected_ports .add (local_port )
254+
255+ builder .add_inbound ({"port" : local_port , "listen" : "127.0.0.1" , "protocol" : "socks" , "tag" : f"inbound-{ local_port } " })
256+ builder .add_outbound (outbound )
257+ builder .config ["routing" ]["rules" ].append ({"type" : "field" , "inboundTag" : [f"inbound-{ local_port } " ], "outboundTag" : unique_outbound_tag })
258+
259+ if not items_to_test_in_batch :
260+ print ("No Xray-compatible configurations found in this batch. Skipping." )
261+ continue
262+
263+ try :
264+ with XrayCore (vendor_path = str (VENDOR_PATH ), config_builder = builder , debug_mode = True ) as xray :
265+ time .sleep (1 )
269266 if not xray .is_running ():
270- print ("\n --- XRAY CRASHED! ---" )
271- break
272- ports_to_check = expected_ports - ready_ports
273- for port in ports_to_check :
274- try :
275- with socket .create_connection (("127.0.0.1" , port ), timeout = 0.25 ):
276- ready_ports .add (port )
277- except (socket .timeout , ConnectionRefusedError ):
278- pass
279- if ready_ports == expected_ports :
280- print (f"All { len (expected_ports )} ports are ready." )
281- break
282- time .sleep (0.25 )
283- else :
284- if xray .is_running ():
285- raise RuntimeError (f"Timeout: Not all ports became ready. { len (ready_ports )} /{ len (expected_ports )} ready." )
267+ raise RuntimeError ("Xray process failed to start for this batch. The batch may contain a malformed config." )
268+
269+ print (f" Xray is running for this batch. Waiting for { len (expected_ports )} ports..." )
270+
271+ ready_ports = set ()
272+ for _ in range (40 ):
273+ if not xray .is_running ():
274+ print ("\n --- XRAY CRASHED! Skipping this batch. ---" )
275+ break
276+ ports_to_check = expected_ports - ready_ports
277+ for port in ports_to_check :
278+ try :
279+ with socket .create_connection (("127.0.0.1" , port ), timeout = 0.25 ):
280+ ready_ports .add (port )
281+ except (socket .timeout , ConnectionRefusedError ):
282+ pass
283+ if ready_ports == expected_ports :
284+ print (f" All { len (expected_ports )} ports are ready." )
285+ break
286+ time .sleep (0.25 )
286287 else :
287- raise RuntimeError ("Xray crashed during port check." )
288+ if xray .is_running ():
289+ raise RuntimeError (f" Timeout: Not all ports became ready. { len (ready_ports )} /{ len (expected_ports )} ready." )
290+ else :
291+ raise RuntimeError ("Xray crashed during port check." )
288292
289- if not ready_ports :
290- print ("\n --- No ports became ready. Aborting tests. ---" )
291- return
292293
293- print ("\n --- Starting all checks concurrently ---" )
294- with ThreadPoolExecutor (max_workers = MAX_WORKERS ) as executor :
295- future_to_item = {executor .submit (check_one_proxy , item , test_url ): item for item in items_to_test }
296- for future in as_completed (future_to_item ):
297- if result_uri := future .result ():
298- final_uris_to_write .append (result_uri )
294+ if len (ready_ports ) != len (expected_ports ):
295+ logging .warning (f"Not all ports were ready ({ len (ready_ports )} /{ len (expected_ports )} ). Continuing with what's available." )
299296
300- except Exception as e :
301- logging .critical (f"A critical error occurred: { e } " , exc_info = False )
302297
303- finally :
304- print (f"\n --- Writing { len (final_uris_to_write )} Final Configurations ---" )
305- Path (FINAL_CONFIGS_PATH ).write_text ("\n " .join (final_uris_to_write ) + "\n " )
306- print ("\n --- Script finished successfully! ---" )
298+ print (f" Starting checks for batch..." )
299+ with ThreadPoolExecutor (max_workers = MAX_WORKERS ) as executor :
300+ future_to_item = {executor .submit (check_one_proxy , item , test_url ): item for item in items_to_test_in_batch }
301+ for future in as_completed (future_to_item ):
302+ if result_uri := future .result ():
303+ final_uris_to_write .append (result_uri )
304+
305+ except Exception as e :
306+ logging .error (f" [FAIL] Critical error in batch { i // BATCH_SIZE + 1 } : { e } " , exc_info = False )
307+ logging .warning (" Skipping to the next batch." )
308+ continue
309+
310+ print (f"\n --- Writing { len (final_uris_to_write )} Final Configurations ---" )
311+ Path (FINAL_CONFIGS_PATH ).write_text ("\n " .join (final_uris_to_write ) + "\n " )
312+ print ("\n --- Script finished successfully! ---" )
307313
308314if __name__ == "__main__" :
309315 main ()
0 commit comments