Support for auto-retry on Singbox enable

This commit is contained in:
SimplifiedPrivacy 2026-08-10 16:25:45 -04:00
parent 9d0d140467
commit 2a6b1eacd5

View file

@ -46,17 +46,51 @@ def set_dns_for_singbox(current_state: SystemState):
raise DNSError(dns_result)
# def _attempt_start_with_retry(profile_id: int, quantity_of_attempts: int = 2) -> Result:
# current_attempt = 0
# while current_attempt < quantity_of_attempts:
# activation_result = singbox.start(profile_id)
def launch_singbox_binary(profile_id: int) -> Result:
activation_result = singbox.start(profile_id)
if not activation_result.valid:
return activation_result
# if activation_result.valid:
# return activation_result
# else:
# current_attempt = current_attempt + 1
# logger.error(f"[SINGBOX] Attempt {current_attempt} for Singbox Failed. Because: {activation_result.message}. Trying again..")
process_id = int(activation_result.data)
logger.info(f"Waiting 2 seconds to see if the process id {process_id} is still alive..")
time.sleep(2)
# Evaluate if running.
active = pid_tools.is_running(pid=process_id, process_name="sing-box")
logger.info(f"Process {process_id} is {active}")
if active:
return Result(valid=True, data=process_id)
else:
error_msg = f"While Singbox might have literally allowed the binary to begin, it's killing the process on id {process_id}"
logger.error(f"[{function_name}] {error_msg}")
return Result(valid=False, error_type=ResultError.PROCESS_GOT_KILLED, message=error_msg, data=process_id)
def _attempt_start_with_retry(profile_id: int, quantity_of_attempts: int = 2) -> Result:
current_attempt = 0
while current_attempt < quantity_of_attempts:
activation_result = launch_singbox_binary(profile_id)
if activation_result.valid:
return activation_result
else:
current_attempt = current_attempt + 1
logger.error(f"[SINGBOX] Attempt {current_attempt} for Singbox Failed. Because: {activation_result.message}. Trying again in two seconds..")
time.sleep(2)
# end of loop / make sure it's not running already..
error_msg = f"Singbox failed to launch after {quantity_of_attempts} attempts"
logger.error(f"{error_msg}, let's double check it's not running already:")
double_check = pid_tools.get_pid_by_app_name(exact_app_name="sing-box")
if double_check.valid:
return double_check
else:
# I'd like to clarify the error_type here, instead of just returning the pid check or an individual attempt.
return Result(valid=False, error_type=PROCESS_WONT_START, message=error_msg)
def end_singbox(
@ -121,28 +155,6 @@ def end_singbox(
return Result(valid=False, error_type=ResultError.SINGBOX, message=error_msg)
def launch_singbox_binary(profile_id: int) -> Result:
activation_result = singbox.start(profile_id)
if not activation_result.valid:
return activation_result
process_id = int(activation_result.data)
logger.info(f"Waiting 2 seconds to see if the process id {process_id} is still alive..")
time.sleep(2)
# Evaluate if running.
active = pid_tools.is_running(pid=process_id, process_name="sing-box")
logger.info(f"Process {process_id} is {active}")
if active:
return Result(valid=True, data=process_id)
else:
error_msg = f"While Singbox might have literally allowed the binary to begin, it's killing the process on id {process_id}"
logger.error(f"[{function_name}] {error_msg}")
return Result(valid=False, error_type=ResultError.PROCESS_GOT_KILLED, message=error_msg, data=process_id)
def start_singbox(
profile_id: int,
@ -177,7 +189,7 @@ def start_singbox(
return killed_pre_existing
# ============= START BINARY =============
launched = launch_singbox_binary(profile_id=profile_id)
launched = _attempt_start_with_retry(profile_id=profile_id, quantity_of_attempts=2)
if not launched.valid:
return launched