MCPcopy Create free account
hub / github.com/78/tenbox / ThreadMain

Method ThreadMain

src/daemon/cloud_tunnel.cpp:796–912  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

794}
795
796void CloudTunnel::ThreadMain() {
797 pthread_setname_np(pthread_self(), "cloud-tunnel");
798 // Exponential backoff for reconnect attempts. Caps at 60s so a flaky
799 // network or temporary cloud outage does not keep the journal at the
800 // previous 1-attempt-per-second cadence (which on a host with broken
801 // IPv6 + AF_UNSPEC produced ~30k log lines/day for nothing). Reset
802 // only after the link has been *up* for kBackoffResetThreshold so a
803 // pathological connect-then-immediately-disconnect loop still backs
804 // off instead of hot-spinning at 1Hz.
805 using Clock = std::chrono::steady_clock;
806 constexpr auto kBackoffMin = std::chrono::seconds(1);
807 constexpr auto kBackoffMax = std::chrono::seconds(60);
808 constexpr auto kBackoffResetThreshold = std::chrono::seconds(30);
809 auto backoff = kBackoffMin;
810 auto bump_backoff = [&]() {
811 backoff = std::min(backoff * 2, kBackoffMax);
812 };
813 // Sleep `delay` but wake early on shutdown so SIGTERM doesn't have
814 // to wait out a full 60s slot during the backoff phase.
815 auto interruptible_sleep = [this](std::chrono::seconds delay) {
816 const auto deadline = Clock::now() + delay;
817 while (running_ && Clock::now() < deadline) {
818 const auto remaining = std::chrono::duration_cast<std::chrono::milliseconds>(
819 deadline - Clock::now());
820 const auto slice = std::min<std::chrono::milliseconds>(
821 remaining, std::chrono::milliseconds(200));
822 std::this_thread::sleep_for(slice);
823 }
824 };
825
826 while (running_) {
827 // Refresh the token snapshot at the top of each connect attempt so
828 // a successful pair (which writes device.token mid-session) takes
829 // effect on the very next reconnect without a daemon restart.
830 {
831 std::lock_guard<std::mutex> lock(pair_mu_);
832 device_token_ = LoadDeviceToken(config_.data_dir);
833 if (device_token_.empty()) {
834 if (pair_code_.empty()) pair_code_ = GeneratePairCode();
835 } else {
836 pair_code_.clear();
837 }
838 }
839
840 std::string error;
841 if (!Connect(&error)) {
842 std::cerr << "cloud tunnel connect failed: " << error
843 << " (retrying in " << backoff.count() << "s)\n";
844 interruptible_sleep(backoff);
845 bump_backoff();
846 continue;
847 }
848
849 const auto connected_at = Clock::now();
850 std::cerr << "cloud tunnel connected as " << host_id_ << "\n";
851 SendJson(HelloPayload());
852 // Once the WS upgrade succeeds and we know we still need pairing,
853 // surface the URL so an operator running `curl ... | sh` sees it

Callers

nothing calls this directly

Calls 4

LoadDeviceTokenFunction · 0.85
GeneratePairCodeFunction · 0.85
PairUrlForFunction · 0.85
FormatPairCodeChunkedFunction · 0.85

Tested by

no test coverage detected