From a0650b9fdd4ffd4453093c96f0e185b1da55b376 Mon Sep 17 00:00:00 2001 From: Elias Renman Date: Fri, 26 Jun 2026 14:01:58 +0200 Subject: [PATCH] Retry Telebit client connections --- README.md | 7 +++++++ telebitctl | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e12e3c9..fbbdeb3 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,13 @@ telebitctl up app 3000 telebitctl up api 8080 ``` +`up` restarts the client if the WebSocket connection drops. By default it waits 5 seconds and retries forever. You can tune that with: + +```sh +TELEBIT_RETRY_DELAY=10 telebitctl up app 3000 +TELEBIT_RETRY_MAX=3 telebitctl up app 3000 +``` + Rotate the client key: ```sh diff --git a/telebitctl b/telebitctl index 7aa35c9..61fb687 100755 --- a/telebitctl +++ b/telebitctl @@ -7,6 +7,8 @@ CLIENT_ENV="${TELEBIT_CLIENT_ENV:-$ROOT_DIR/telebit-client.env}" CLIENT_ENV_DIR="${TELEBIT_CLIENT_ENV_DIR:-$ROOT_DIR/.telebit-clients}" TELEBIT_BIN="${TELEBIT_BIN:-$ROOT_DIR/bin/telebit}" SIGNJWT_BIN="${SIGNJWT_BIN:-$ROOT_DIR/bin/signjwt}" +TELEBIT_RETRY_DELAY="${TELEBIT_RETRY_DELAY:-5}" +TELEBIT_RETRY_MAX="${TELEBIT_RETRY_MAX:-0}" usage() { cat <<'USAGE' @@ -190,6 +192,46 @@ refresh_auth() { printf 'Bound %s.%s\n' "$slug" "$DOMAIN" } +run_client_with_retries() { + env_file="$1" + attempts=0 + stop_requested=false + child_pid="" + + case "$TELEBIT_RETRY_DELAY" in + ""|*[!0-9]*) die "TELEBIT_RETRY_DELAY must be a non-negative integer" ;; + esac + case "$TELEBIT_RETRY_MAX" in + ""|*[!0-9]*) die "TELEBIT_RETRY_MAX must be a non-negative integer" ;; + esac + + trap 'stop_requested=true; if [ -n "$child_pid" ]; then kill "$child_pid" 2>/dev/null || true; fi' INT TERM + + while :; do + "$TELEBIT_BIN" --env "$env_file" & + child_pid=$! + if wait "$child_pid"; then + status=0 + else + status=$? + fi + child_pid="" + + if [ "$stop_requested" = "true" ]; then + exit "$status" + fi + + attempts=$((attempts + 1)) + if [ "$TELEBIT_RETRY_MAX" != "0" ] && [ "$attempts" -ge "$TELEBIT_RETRY_MAX" ]; then + printf 'Telebit exited with status %s after %s attempt(s); not retrying.\n' "$status" "$attempts" >&2 + exit "$status" + fi + + printf 'Telebit exited with status %s; retrying in %ss.\n' "$status" "$TELEBIT_RETRY_DELAY" >&2 + sleep "$TELEBIT_RETRY_DELAY" || exit "$?" + done +} + up_client() { load_server_env need_bin "$TELEBIT_BIN" @@ -206,7 +248,7 @@ up_client() { write_client_env "$slug" "$key" "$port" "$env_file" >/dev/null unset SECRET DOMAIN TUNNEL_DOMAIN MGMT_URL POSTGRES_PASSWORD TELEBIT_PORT MGMT_PORT VENDOR_ID cd "$HOME" - exec "$TELEBIT_BIN" --env "$env_file" + run_client_with_retries "$env_file" } build_client() {