| 23 | } |
| 24 | |
| 25 | void ReplicasStatusHandler::handleRequest(HTTPServerRequest & request, HTTPServerResponse & response) |
| 26 | { |
| 27 | try |
| 28 | { |
| 29 | HTMLForm params(getContext()->getSettingsRef(), request); |
| 30 | |
| 31 | /// Even if lag is small, output detailed information about the lag. |
| 32 | bool verbose = params.get("verbose", "") == "1"; |
| 33 | |
| 34 | const MergeTreeSettings & settings = getContext()->getReplicatedMergeTreeSettings(); |
| 35 | |
| 36 | bool ok = true; |
| 37 | WriteBufferFromOwnString message; |
| 38 | |
| 39 | auto databases = DatabaseCatalog::instance().getDatabases(getContext()); |
| 40 | |
| 41 | /// Iterate through all the replicated tables. |
| 42 | for (const auto & db : databases) |
| 43 | { |
| 44 | /// Check if database can contain replicated tables |
| 45 | if (!db.second->canContainMergeTreeTables()) |
| 46 | continue; |
| 47 | |
| 48 | for (auto iterator = db.second->getTablesIterator(getContext()); iterator->isValid(); iterator->next()) |
| 49 | { |
| 50 | const auto & table = iterator->table(); |
| 51 | if (!table) |
| 52 | continue; |
| 53 | |
| 54 | StorageReplicatedMergeTree * table_replicated = dynamic_cast<StorageReplicatedMergeTree *>(table.get()); |
| 55 | |
| 56 | if (!table_replicated) |
| 57 | continue; |
| 58 | |
| 59 | time_t absolute_delay = 0; |
| 60 | time_t relative_delay = 0; |
| 61 | |
| 62 | table_replicated->getReplicaDelays(absolute_delay, relative_delay); |
| 63 | |
| 64 | if ((settings.min_absolute_delay_to_close && absolute_delay >= static_cast<time_t>(settings.min_absolute_delay_to_close)) |
| 65 | || (settings.min_relative_delay_to_close && relative_delay >= static_cast<time_t>(settings.min_relative_delay_to_close))) |
| 66 | ok = false; |
| 67 | |
| 68 | message << backQuoteIfNeed(db.first) << "." << backQuoteIfNeed(iterator->name()) |
| 69 | << ":\tAbsolute delay: " << absolute_delay << ". Relative delay: " << relative_delay << ".\n"; |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | const auto & config = getContext()->getConfigRef(); |
| 74 | setResponseDefaultHeaders(response, config.getUInt("keep_alive_timeout", 10)); |
| 75 | |
| 76 | if (!ok) |
| 77 | { |
| 78 | response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_SERVICE_UNAVAILABLE); |
| 79 | verbose = true; |
| 80 | } |
| 81 | |
| 82 | if (verbose) |
nothing calls this directly
no test coverage detected