|
@@ -578,9 +578,9 @@ void RunnerService::start() {
|
|
|
running_ = true;
|
|
running_ = true;
|
|
|
|
|
|
|
|
// Register with webserver
|
|
// Register with webserver
|
|
|
- registerWithWebServer();
|
|
|
|
|
|
|
+ registered_ = registerWithWebServer();
|
|
|
|
|
|
|
|
- // Start heartbeat
|
|
|
|
|
|
|
+ // Start heartbeat, which also re-registers whenever the webserver forgets us
|
|
|
heartbeat_thread_ = std::thread(&RunnerService::heartbeatLoop, this);
|
|
heartbeat_thread_ = std::thread(&RunnerService::heartbeatLoop, this);
|
|
|
|
|
|
|
|
LOG_INFO("Runner service {} started", config_.runner_id);
|
|
LOG_INFO("Runner service {} started", config_.runner_id);
|
|
@@ -619,7 +619,7 @@ void RunnerService::stop() {
|
|
|
LOG_INFO("Runner service stopped");
|
|
LOG_INFO("Runner service stopped");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void RunnerService::registerWithWebServer() {
|
|
|
|
|
|
|
+bool RunnerService::registerWithWebServer() {
|
|
|
// Use HTTP to register with webserver
|
|
// Use HTTP to register with webserver
|
|
|
nlohmann::json body;
|
|
nlohmann::json body;
|
|
|
body["id"] = config_.runner_id;
|
|
body["id"] = config_.runner_id;
|
|
@@ -640,7 +640,7 @@ void RunnerService::registerWithWebServer() {
|
|
|
CURL* curl = curl_easy_init();
|
|
CURL* curl = curl_easy_init();
|
|
|
if (!curl) {
|
|
if (!curl) {
|
|
|
LOG_WARN("Failed to initialize curl for registration");
|
|
LOG_WARN("Failed to initialize curl for registration");
|
|
|
- return;
|
|
|
|
|
|
|
+ return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
std::string response_data;
|
|
std::string response_data;
|
|
@@ -664,14 +664,26 @@ void RunnerService::registerWithWebServer() {
|
|
|
|
|
|
|
|
CURLcode res = curl_easy_perform(curl);
|
|
CURLcode res = curl_easy_perform(curl);
|
|
|
|
|
|
|
|
|
|
+ long http_code = 0;
|
|
|
if (res == CURLE_OK) {
|
|
if (res == CURLE_OK) {
|
|
|
|
|
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // A transport-level success is not enough: the webserver can still reject the
|
|
|
|
|
+ // registration, and reporting that as success would hide a runner that is not
|
|
|
|
|
+ // actually reachable for work.
|
|
|
|
|
+ const bool ok = (res == CURLE_OK && http_code >= 200 && http_code < 300);
|
|
|
|
|
+ if (ok) {
|
|
|
LOG_INFO("Runner registered with webserver");
|
|
LOG_INFO("Runner registered with webserver");
|
|
|
- } else {
|
|
|
|
|
|
|
+ } else if (res != CURLE_OK) {
|
|
|
LOG_WARN("Failed to register with webserver: {}", curl_easy_strerror(res));
|
|
LOG_WARN("Failed to register with webserver: {}", curl_easy_strerror(res));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ LOG_WARN("Webserver rejected registration: HTTP {}", http_code);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
curl_slist_free_all(headers);
|
|
curl_slist_free_all(headers);
|
|
|
curl_easy_cleanup(curl);
|
|
curl_easy_cleanup(curl);
|
|
|
|
|
+ return ok;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void RunnerService::heartbeatLoop() {
|
|
void RunnerService::heartbeatLoop() {
|
|
@@ -728,12 +740,38 @@ void RunnerService::heartbeatLoop() {
|
|
|
|
|
|
|
|
CURLcode res = curl_easy_perform(curl);
|
|
CURLcode res = curl_easy_perform(curl);
|
|
|
|
|
|
|
|
- if (res != CURLE_OK) {
|
|
|
|
|
- LOG_WARN("Heartbeat failed: {}", curl_easy_strerror(res));
|
|
|
|
|
|
|
+ long http_code = 0;
|
|
|
|
|
+ if (res == CURLE_OK) {
|
|
|
|
|
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
curl_slist_free_all(headers);
|
|
curl_slist_free_all(headers);
|
|
|
curl_easy_cleanup(curl);
|
|
curl_easy_cleanup(curl);
|
|
|
|
|
+
|
|
|
|
|
+ if (res == CURLE_OK && http_code >= 200 && http_code < 300) {
|
|
|
|
|
+ if (!registered_) {
|
|
|
|
|
+ LOG_INFO("Reconnected to webserver");
|
|
|
|
|
+ registered_ = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // The registry lives in webserver memory, so a webserver restart forgets
|
|
|
|
|
+ // this runner while the runner itself stays healthy. It answers 404 for an
|
|
|
|
|
+ // unknown runner; without re-registering here the runner would stay
|
|
|
|
|
+ // invisible and every execution would fail with "no runners available".
|
|
|
|
|
+ if (registered_) {
|
|
|
|
|
+ if (res != CURLE_OK) {
|
|
|
|
|
+ LOG_WARN("Heartbeat failed: {}", curl_easy_strerror(res));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ LOG_WARN("Heartbeat rejected: HTTP {}", http_code);
|
|
|
|
|
+ }
|
|
|
|
|
+ registered_ = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (registerWithWebServer()) {
|
|
|
|
|
+ registered_ = true;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|