aboutsummaryrefslogtreecommitdiffstats
path: root/searchcore
diff options
context:
space:
mode:
Diffstat (limited to 'searchcore')
-rw-r--r--searchcore/src/vespa/searchcore/proton/flushengine/flushengine.h5
-rw-r--r--searchcore/src/vespa/searchcore/proton/matchengine/matchengine.h5
-rw-r--r--searchcore/src/vespa/searchcore/proton/metrics/documentdb_tagged_metrics.cpp3
-rw-r--r--searchcore/src/vespa/searchcore/proton/metrics/documentdb_tagged_metrics.h4
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/CMakeLists.txt2
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/documentdb.cpp31
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/documentdb.h43
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.cpp11
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.h5
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/executor_explorer_utils.cpp57
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/executor_explorer_utils.h16
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/executor_threading_service_explorer.cpp44
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/proton.cpp39
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/proton.h40
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/proton_thread_pools_explorer.cpp43
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/proton_thread_pools_explorer.h35
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/storeonlydocsubdb.cpp5
-rw-r--r--searchcore/src/vespa/searchcore/proton/server/storeonlydocsubdb.h5
-rw-r--r--searchcore/src/vespa/searchcore/proton/summaryengine/summaryengine.h5
19 files changed, 266 insertions, 132 deletions
diff --git a/searchcore/src/vespa/searchcore/proton/flushengine/flushengine.h b/searchcore/src/vespa/searchcore/proton/flushengine/flushengine.h
index 2a7115f4d33..160423c7c68 100644
--- a/searchcore/src/vespa/searchcore/proton/flushengine/flushengine.h
+++ b/searchcore/src/vespa/searchcore/proton/flushengine/flushengine.h
@@ -112,6 +112,11 @@ public:
vespalib::ThreadStackExecutor::Stats getExecutorStats() { return _executor.getStats(); }
/**
+ * Returns the underlying executor. Only used for state explorers.
+ */
+ const vespalib::SyncableThreadExecutor& get_executor() const { return _executor; }
+
+ /**
* Starts the scheduling thread of this manager.
*
* @return This, to allow chaining.
diff --git a/searchcore/src/vespa/searchcore/proton/matchengine/matchengine.h b/searchcore/src/vespa/searchcore/proton/matchengine/matchengine.h
index 34aacdafcad..8adc198bb40 100644
--- a/searchcore/src/vespa/searchcore/proton/matchengine/matchengine.h
+++ b/searchcore/src/vespa/searchcore/proton/matchengine/matchengine.h
@@ -60,6 +60,11 @@ public:
vespalib::ThreadStackExecutor::Stats getExecutorStats() { return _executor.getStats(); }
/**
+ * Returns the underlying executor. Only used for state explorers.
+ */
+ const vespalib::SyncableThreadExecutor& get_executor() const { return _executor; }
+
+ /**
* Closes the request handler interface. This will prevent any more data
* from entering this object, allowing you to flush all pending operations
* without having to safe-guard against input.
diff --git a/searchcore/src/vespa/searchcore/proton/metrics/documentdb_tagged_metrics.cpp b/searchcore/src/vespa/searchcore/proton/metrics/documentdb_tagged_metrics.cpp
index 3b1a21a7e2f..7b7fcc9e45d 100644
--- a/searchcore/src/vespa/searchcore/proton/metrics/documentdb_tagged_metrics.cpp
+++ b/searchcore/src/vespa/searchcore/proton/metrics/documentdb_tagged_metrics.cpp
@@ -194,7 +194,8 @@ DocumentDBTaggedMetrics::MatchingMetrics::RankProfileMetrics::DocIdPartition::up
}
void
-DocumentDBTaggedMetrics::MatchingMetrics::RankProfileMetrics::update(const MatchingStats &stats)
+DocumentDBTaggedMetrics::MatchingMetrics::RankProfileMetrics::update(const metrics::MetricLockGuard &,
+ const MatchingStats &stats)
{
docsMatched.inc(stats.docsMatched());
docsRanked.inc(stats.docsRanked());
diff --git a/searchcore/src/vespa/searchcore/proton/metrics/documentdb_tagged_metrics.h b/searchcore/src/vespa/searchcore/proton/metrics/documentdb_tagged_metrics.h
index 26dd52a8577..133df81a9e6 100644
--- a/searchcore/src/vespa/searchcore/proton/metrics/documentdb_tagged_metrics.h
+++ b/searchcore/src/vespa/searchcore/proton/metrics/documentdb_tagged_metrics.h
@@ -9,6 +9,8 @@
#include <vespa/metrics/valuemetric.h>
#include <vespa/searchcore/proton/matching/matching_stats.h>
+namespace metrics { class MetricLockGuard; }
+
namespace proton {
/**
@@ -154,7 +156,7 @@ struct DocumentDBTaggedMetrics : metrics::MetricSet
size_t numDocIdPartitions,
metrics::MetricSet *parent);
~RankProfileMetrics() override;
- void update(const matching::MatchingStats &stats);
+ void update(const metrics::MetricLockGuard & guard, const matching::MatchingStats &stats);
};
using RankProfileMap = std::map<vespalib::string, RankProfileMetrics::UP>;
diff --git a/searchcore/src/vespa/searchcore/proton/server/CMakeLists.txt b/searchcore/src/vespa/searchcore/proton/server/CMakeLists.txt
index 81dd8a64a6c..73b7404ce31 100644
--- a/searchcore/src/vespa/searchcore/proton/server/CMakeLists.txt
+++ b/searchcore/src/vespa/searchcore/proton/server/CMakeLists.txt
@@ -35,6 +35,7 @@ vespa_add_library(searchcore_server STATIC
documentretrieverbase.cpp
documentsubdbcollection.cpp
emptysearchview.cpp
+ executor_explorer_utils.cpp
executor_thread_service.cpp
executor_threading_service_explorer.cpp
executorthreadingservice.cpp
@@ -77,6 +78,7 @@ vespa_add_library(searchcore_server STATIC
proton_config_snapshot.cpp
proton_configurer.cpp
proton_disk_layout.cpp
+ proton_thread_pools_explorer.cpp
prune_session_cache_job.cpp
pruneremoveddocumentsjob.cpp
putdonecontext.cpp
diff --git a/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp b/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp
index c7b5aaafbfc..7323744c626 100644
--- a/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/documentdb.cpp
@@ -35,6 +35,7 @@
#include <vespa/searchlib/common/gatecallback.h>
#include <vespa/vespalib/util/closuretask.h>
#include <vespa/vespalib/util/exceptions.h>
+#include <vespa/metrics/updatehook.h>
#include <vespa/log/log.h>
#include <vespa/searchcorespi/index/warmupconfig.h>
@@ -102,6 +103,18 @@ findDocumentDB(const ProtonConfig::DocumentdbVector & documentDBs, const vespali
return &_G_defaultProtonDocumentDBConfig;
}
+class MetricsUpdateHook : public metrics::UpdateHook {
+ DocumentDB &_db;
+public:
+ MetricsUpdateHook(DocumentDB &s)
+ : metrics::UpdateHook("documentdb-hook"),
+ _db(s)
+ {}
+ void updateMetrics(const MetricLockGuard & guard) override {
+ _db.updateMetrics(guard);
+ }
+};
+
}
template <typename FunctionType>
@@ -147,7 +160,6 @@ DocumentDB::DocumentDB(const vespalib::string &baseDir,
_configCV(),
_activeConfigSnapshot(),
_activeConfigSnapshotGeneration(0),
- _activeConfigSnapshotSerialNum(0u),
_validateAndSanitizeDocStore(protonCfg.validateAndSanitizeDocstore == vespa::config::search::core::ProtonConfig::ValidateAndSanitizeDocstore::YES),
_initGate(),
_clusterStateHandler(_writeService.master()),
@@ -156,7 +168,8 @@ DocumentDB::DocumentDB(const vespalib::string &baseDir,
_config_store(std::move(config_store)),
_sessionManager(std::make_shared<matching::SessionManager>(protonCfg.grouping.sessionmanager.maxentries)),
_metricsWireService(metricsWireService),
- _metricsHook(*this, _docTypeName.getName(), protonCfg.numthreadspersearch),
+ _metrics(_docTypeName.getName(), protonCfg.numthreadspersearch),
+ _metricsHook(std::make_unique<MetricsUpdateHook>(*this)),
_feedView(),
_refCount(),
_syncFeedViewEnabled(false),
@@ -176,7 +189,7 @@ DocumentDB::DocumentDB(const vespalib::string &baseDir,
_lidSpaceCompactionHandlers(),
_jobTrackers(),
_calc(),
- _metricsUpdater(_subDBs, _writeService, _jobTrackers, *_sessionManager, _writeFilter, _state)
+ _metricsUpdater(_subDBs, _writeService, _jobTrackers, *_sessionManager, _writeFilter)
{
assert(configSnapshot);
@@ -222,8 +235,7 @@ void DocumentDB::registerReference()
}
}
-void DocumentDB::setActiveConfig(const DocumentDBConfig::SP &config,
- SerialNum serialNum, int64_t generation) {
+void DocumentDB::setActiveConfig(const DocumentDBConfig::SP &config, int64_t generation) {
lock_guard guard(_configMutex);
registerReference();
_activeConfigSnapshot = config;
@@ -231,7 +243,6 @@ void DocumentDB::setActiveConfig(const DocumentDBConfig::SP &config,
if (_activeConfigSnapshotGeneration < generation) {
_activeConfigSnapshotGeneration = generation;
}
- _activeConfigSnapshotSerialNum = serialNum;
_configCV.notify_all();
}
@@ -297,7 +308,7 @@ DocumentDB::initFinish(DocumentDBConfig::SP configSnapshot)
syncFeedView();
// Check that feed view has been activated.
assert(_feedView.get());
- setActiveConfig(configSnapshot, _initConfigSerialNum, configSnapshot->getGeneration());
+ setActiveConfig(configSnapshot, configSnapshot->getGeneration());
startTransactionLogReplay();
}
@@ -469,7 +480,7 @@ DocumentDB::applyConfig(DocumentDBConfig::SP configSnapshot, SerialNum serialNum
}
_state.clearDelayedConfig();
}
- setActiveConfig(configSnapshot, serialNum, generation);
+ setActiveConfig(configSnapshot, generation);
if (params.shouldMaintenanceControllerChange()) {
forwardMaintenanceConfig();
}
@@ -1042,12 +1053,12 @@ DocumentDB::notifyAllBucketsChanged()
}
void
-DocumentDB::updateMetrics(DocumentDBTaggedMetrics &metrics)
+DocumentDB::updateMetrics(const metrics::MetricLockGuard & guard)
{
if (_state.getState() < DDBState::State::REPLAY_TRANSACTION_LOG) {
return;
}
- _metricsUpdater.updateMetrics(metrics);
+ _metricsUpdater.updateMetrics(guard, _metrics);
}
void
diff --git a/searchcore/src/vespa/searchcore/proton/server/documentdb.h b/searchcore/src/vespa/searchcore/proton/server/documentdb.h
index a171861b590..9ea88360b07 100644
--- a/searchcore/src/vespa/searchcore/proton/server/documentdb.h
+++ b/searchcore/src/vespa/searchcore/proton/server/documentdb.h
@@ -18,7 +18,6 @@
#include "ireplayconfig.h"
#include "maintenancecontroller.h"
#include "threading_service_config.h"
-#include <vespa/metrics/updatehook.h>
#include <vespa/searchcore/proton/attribute/attribute_usage_filter.h>
#include <vespa/searchcore/proton/common/doctypename.h>
#include <vespa/searchcore/proton/common/monitored_refcount.h>
@@ -42,6 +41,10 @@ namespace search {
}
namespace vespa::config::search::core::internal { class InternalProtonType; }
+namespace metrics {
+ class UpdateHook;
+ class MetricLockGuard;
+}
namespace proton {
class AttributeConfigInspector;
@@ -68,26 +71,6 @@ class DocumentDB : public DocumentDBConfigOwner,
public search::transactionlog::SyncProxy
{
private:
- class MetricsUpdateHook : public metrics::UpdateHook {
- DocumentDBTaggedMetrics _metrics;
- DocumentDB &_db;
- public:
- MetricsUpdateHook(DocumentDB &s, const std::string &doc_type, size_t maxNumThreads)
- : metrics::UpdateHook("documentdb-hook"),
- _metrics(doc_type, maxNumThreads),
- _db(s) {}
- void updateMetrics(const MetricLockGuard & ) override { _db.updateMetrics(_metrics); }
- DocumentDBTaggedMetrics &getMetrics() { return _metrics; }
- };
-
- struct DocumentStoreCacheStats {
- search::CacheStats total;
- search::CacheStats readySubDb;
- search::CacheStats notReadySubDb;
- search::CacheStats removedSubDb;
- DocumentStoreCacheStats() : total(), readySubDb(), notReadySubDb(), removedSubDb() {}
- };
-
using InitializeThreads = std::shared_ptr<vespalib::SyncableThreadExecutor>;
using IFlushTargetList = std::vector<std::shared_ptr<searchcorespi::IFlushTarget>>;
using StatusReportUP = std::unique_ptr<StatusReport>;
@@ -114,7 +97,6 @@ private:
mutable std::condition_variable _configCV;
DocumentDBConfig::SP _activeConfigSnapshot;
int64_t _activeConfigSnapshotGeneration;
- SerialNum _activeConfigSnapshotSerialNum;
const bool _validateAndSanitizeDocStore;
vespalib::Gate _initGate;
@@ -126,9 +108,10 @@ private:
index::IndexConfig _indexCfg;
ConfigStore::UP _config_store;
std::shared_ptr<matching::SessionManager> _sessionManager; // TODO: This should not have to be a shared pointer.
- MetricsWireService &_metricsWireService;
- MetricsUpdateHook _metricsHook;
- vespalib::VarHolder<IFeedView::SP> _feedView;
+ MetricsWireService &_metricsWireService;
+ DocumentDBTaggedMetrics _metrics;
+ std::unique_ptr<metrics::UpdateHook> _metricsHook;
+ vespalib::VarHolder<IFeedView::SP> _feedView;
MonitoredRefCount _refCount;
bool _syncFeedViewEnabled;
IDocumentDBOwner &_owner;
@@ -145,7 +128,7 @@ private:
DocumentDBMetricsUpdater _metricsUpdater;
void registerReference();
- void setActiveConfig(const DocumentDBConfig::SP &config, SerialNum serialNum, int64_t generation);
+ void setActiveConfig(const DocumentDBConfig::SP &config, int64_t generation);
DocumentDBConfig::SP getActiveConfig() const;
void internalInit();
void initManagers();
@@ -294,7 +277,9 @@ public:
*
* @return document db metrics
**/
- DocumentDBTaggedMetrics &getMetrics() { return _metricsHook.getMetrics(); }
+ DocumentDBTaggedMetrics &getMetrics() {
+ return _metrics;
+ }
/**
* Obtain the metrics update hook for this document db.
@@ -302,7 +287,7 @@ public:
* @return metrics update hook
**/
metrics::UpdateHook & getMetricsUpdateHook() {
- return _metricsHook;
+ return *_metricsHook;
}
/**
@@ -414,7 +399,7 @@ public:
* the metric manager). Do not call this function in multiple
* threads at once.
**/
- void updateMetrics(DocumentDBTaggedMetrics &metrics);
+ void updateMetrics(const metrics::MetricLockGuard & guard);
/**
* Implement search::transactionlog::SyncProxy API.
diff --git a/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.cpp b/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.cpp
index 3a086046a27..8b923c7a372 100644
--- a/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.cpp
@@ -34,8 +34,7 @@ DocumentDBMetricsUpdater::DocumentDBMetricsUpdater(const DocumentSubDBCollection
ExecutorThreadingService &writeService,
DocumentDBJobTrackers &jobTrackers,
matching::SessionManager &sessionManager,
- const AttributeUsageFilter &writeFilter,
- [[maybe_unused]] const DDBState &state)
+ const AttributeUsageFilter &writeFilter)
: _subDBs(subDBs),
_writeService(writeService),
_jobTrackers(jobTrackers),
@@ -170,12 +169,12 @@ updateAttributeMetrics(DocumentDBTaggedMetrics &metrics, const DocumentSubDBColl
}
void
-updateMatchingMetrics(DocumentDBTaggedMetrics &metrics, const IDocumentSubDB &ready)
+updateMatchingMetrics(const metrics::MetricLockGuard & guard, DocumentDBTaggedMetrics &metrics, const IDocumentSubDB &ready)
{
MatchingStats totalStats;
for (const auto &rankProfile : metrics.matching.rank_profiles) {
MatchingStats matchingStats = ready.getMatcherStats(rankProfile.first);
- rankProfile.second->update(matchingStats);
+ rankProfile.second->update(guard, matchingStats);
totalStats.add(matchingStats);
}
@@ -284,13 +283,13 @@ updateLidSpaceMetrics(MetricSetType &metrics, const search::IDocumentMetaStore &
}
void
-DocumentDBMetricsUpdater::updateMetrics(DocumentDBTaggedMetrics &metrics)
+DocumentDBMetricsUpdater::updateMetrics(const metrics::MetricLockGuard & guard, DocumentDBTaggedMetrics &metrics)
{
TotalStats totalStats;
ExecutorThreadingServiceStats threadingServiceStats = _writeService.getStats();
updateIndexMetrics(metrics, _subDBs.getReadySubDB()->getSearchableStats(), totalStats);
updateAttributeMetrics(metrics, _subDBs, totalStats);
- updateMatchingMetrics(metrics, *_subDBs.getReadySubDB());
+ updateMatchingMetrics(guard, metrics, *_subDBs.getReadySubDB());
updateSessionCacheMetrics(metrics, _sessionManager);
updateDocumentsMetrics(metrics, _subDBs);
updateDocumentStoreMetrics(metrics, _subDBs, _lastDocStoreCacheStats, totalStats);
diff --git a/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.h b/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.h
index dbf4c45007f..475da7f4e4c 100644
--- a/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.h
+++ b/searchcore/src/vespa/searchcore/proton/server/documentdb_metrics_updater.h
@@ -45,11 +45,10 @@ public:
ExecutorThreadingService &writeService,
DocumentDBJobTrackers &jobTrackers,
matching::SessionManager &sessionManager,
- const AttributeUsageFilter &writeFilter,
- const DDBState &state);
+ const AttributeUsageFilter &writeFilter);
~DocumentDBMetricsUpdater();
- void updateMetrics(DocumentDBTaggedMetrics &metrics);
+ void updateMetrics(const metrics::MetricLockGuard & guard, DocumentDBTaggedMetrics &metrics);
};
diff --git a/searchcore/src/vespa/searchcore/proton/server/executor_explorer_utils.cpp b/searchcore/src/vespa/searchcore/proton/server/executor_explorer_utils.cpp
new file mode 100644
index 00000000000..bbb87099988
--- /dev/null
+++ b/searchcore/src/vespa/searchcore/proton/server/executor_explorer_utils.cpp
@@ -0,0 +1,57 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "executor_explorer_utils.h"
+#include <vespa/vespalib/data/slime/cursor.h>
+#include <vespa/vespalib/util/blockingthreadstackexecutor.h>
+#include <vespa/vespalib/util/singleexecutor.h>
+#include <vespa/vespalib/util/threadexecutor.h>
+#include <vespa/vespalib/util/threadstackexecutor.h>
+
+using vespalib::BlockingThreadStackExecutor;
+using vespalib::SingleExecutor;
+using vespalib::SyncableThreadExecutor;
+using vespalib::ThreadStackExecutor;
+using vespalib::slime::Cursor;
+
+
+namespace proton::explorer {
+
+namespace {
+
+void
+convert_syncable_executor_to_slime(const SyncableThreadExecutor& executor, const vespalib::string& type, Cursor& object)
+{
+ object.setString("type", type);
+ object.setLong("num_threads", executor.getNumThreads());
+ object.setLong("task_limit", executor.getTaskLimit());
+}
+
+void
+convert_single_executor_to_slime(const SingleExecutor& executor, Cursor& object)
+{
+ convert_syncable_executor_to_slime(executor, "SingleExecutor", object);
+ object.setLong("watermark", executor.get_watermark());
+ object.setDouble("reaction_time_sec", vespalib::to_s(executor.get_reaction_time()));
+}
+
+}
+
+void
+convert_executor_to_slime(const SyncableThreadExecutor* executor, Cursor& object)
+{
+ if (executor == nullptr) {
+ return;
+ }
+ if (const auto* single = dynamic_cast<const SingleExecutor*>(executor)) {
+ convert_single_executor_to_slime(*single, object);
+ } else if (const auto* blocking = dynamic_cast<const BlockingThreadStackExecutor*>(executor)) {
+ convert_syncable_executor_to_slime(*blocking, "BlockingThreadStackExecutor", object);
+ } else if (const auto* thread = dynamic_cast<const ThreadStackExecutor*>(executor)) {
+ convert_syncable_executor_to_slime(*thread, "ThreadStackExecutor", object);
+ } else {
+ convert_syncable_executor_to_slime(*executor, "SyncableThreadExecutor", object);
+ }
+}
+
+}
+
diff --git a/searchcore/src/vespa/searchcore/proton/server/executor_explorer_utils.h b/searchcore/src/vespa/searchcore/proton/server/executor_explorer_utils.h
new file mode 100644
index 00000000000..0793fa6ac4a
--- /dev/null
+++ b/searchcore/src/vespa/searchcore/proton/server/executor_explorer_utils.h
@@ -0,0 +1,16 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+namespace vespalib { class SyncableThreadExecutor; }
+namespace vespalib::slime { struct Cursor; }
+
+namespace proton::explorer {
+
+/**
+ * Utility to convert an executor to slime for use with a state explorer.
+ */
+void convert_executor_to_slime(const vespalib::SyncableThreadExecutor* executor, vespalib::slime::Cursor& object);
+
+}
+
diff --git a/searchcore/src/vespa/searchcore/proton/server/executor_threading_service_explorer.cpp b/searchcore/src/vespa/searchcore/proton/server/executor_threading_service_explorer.cpp
index 0ecdca54e27..e3154ad6a47 100644
--- a/searchcore/src/vespa/searchcore/proton/server/executor_threading_service_explorer.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/executor_threading_service_explorer.cpp
@@ -1,26 +1,21 @@
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include "executor_explorer_utils.h"
#include "executor_threading_service_explorer.h"
#include "executorthreadingservice.h"
#include <vespa/vespalib/data/slime/cursor.h>
#include <vespa/vespalib/util/adaptive_sequenced_executor.h>
-#include <vespa/vespalib/util/blockingthreadstackexecutor.h>
#include <vespa/vespalib/util/sequencedtaskexecutor.h>
-#include <vespa/vespalib/util/singleexecutor.h>
-#include <vespa/vespalib/util/threadexecutor.h>
-#include <vespa/vespalib/util/threadstackexecutor.h>
using vespalib::AdaptiveSequencedExecutor;
-using vespalib::BlockingThreadStackExecutor;
using vespalib::ISequencedTaskExecutor;
using vespalib::SequencedTaskExecutor;
-using vespalib::SingleExecutor;
-using vespalib::SyncableThreadExecutor;
-using vespalib::ThreadStackExecutor;
using vespalib::slime::Cursor;
namespace proton {
+using explorer::convert_executor_to_slime;
+
namespace {
void
@@ -30,39 +25,6 @@ set_type(Cursor& object, const vespalib::string& type)
}
void
-convert_syncable_executor_to_slime(const SyncableThreadExecutor& executor, const vespalib::string& type, Cursor& object)
-{
- set_type(object, type);
- object.setLong("num_threads", executor.getNumThreads());
- object.setLong("task_limit", executor.getTaskLimit());
-}
-
-void
-convert_single_executor_to_slime(const SingleExecutor& executor, Cursor& object)
-{
- convert_syncable_executor_to_slime(executor, "SingleExecutor", object);
- object.setLong("watermark", executor.get_watermark());
- object.setDouble("reaction_time_sec", vespalib::to_s(executor.get_reaction_time()));
-}
-
-void
-convert_executor_to_slime(const SyncableThreadExecutor* executor, Cursor& object)
-{
- if (executor == nullptr) {
- return;
- }
- if (const auto* single = dynamic_cast<const SingleExecutor*>(executor)) {
- convert_single_executor_to_slime(*single, object);
- } else if (const auto* blocking = dynamic_cast<const BlockingThreadStackExecutor*>(executor)) {
- convert_syncable_executor_to_slime(*blocking, "BlockingThreadStackExecutor", object);
- } else if (const auto* thread = dynamic_cast<const ThreadStackExecutor*>(executor)) {
- convert_syncable_executor_to_slime(*thread, "ThreadStackExecutor", object);
- } else {
- convert_syncable_executor_to_slime(*executor, "SyncableThreadExecutor", object);
- }
-}
-
-void
convert_sequenced_executor_to_slime(const SequencedTaskExecutor& executor, Cursor& object)
{
set_type(object, "SequencedTaskExecutor");
diff --git a/searchcore/src/vespa/searchcore/proton/server/proton.cpp b/searchcore/src/vespa/searchcore/proton/server/proton.cpp
index dddca6a9ddd..36d630bc519 100644
--- a/searchcore/src/vespa/searchcore/proton/server/proton.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/proton.cpp
@@ -10,6 +10,7 @@
#include "proton.h"
#include "proton_config_snapshot.h"
#include "proton_disk_layout.h"
+#include "proton_thread_pools_explorer.h"
#include "resource_usage_explorer.h"
#include "searchhandlerproxy.h"
#include "simpleflush.h"
@@ -34,6 +35,7 @@
#include <vespa/vespalib/util/host_name.h>
#include <vespa/vespalib/util/lambdatask.h>
#include <vespa/vespalib/util/random.h>
+#include <vespa/metrics/updatehook.h>
#include <vespa/searchlib/aggregation/forcelink.hpp>
#include <vespa/searchlib/expression/forcelink.hpp>
@@ -112,6 +114,18 @@ derive_shared_threads(const ProtonConfig &proton,
return std::max(scaledCores, proton.documentdb.size() + proton.flush.maxconcurrent + 1);
}
+struct MetricsUpdateHook : metrics::UpdateHook
+{
+ Proton &self;
+ MetricsUpdateHook(Proton &s)
+ : metrics::UpdateHook("proton-hook"),
+ self(s)
+ {}
+ void updateMetrics(const MetricLockGuard &guard) override {
+ self.updateMetrics(guard);
+ }
+};
+
const vespalib::string CUSTOM_COMPONENT_API_PATH = "/state/v1/custom/component";
VESPA_THREAD_STACK_TAG(proton_shared_executor)
@@ -121,7 +135,7 @@ VESPA_THREAD_STACK_TAG(close_executor)
}
-Proton::ProtonFileHeaderContext::ProtonFileHeaderContext([[maybe_unused]] const Proton &proton_, const vespalib::string &creator)
+Proton::ProtonFileHeaderContext::ProtonFileHeaderContext(const vespalib::string &creator)
: _hostName(),
_creator(creator),
_cluster(),
@@ -186,9 +200,9 @@ Proton::Proton(const config::ConfigUri & configUri,
ComponentConfigProducer(),
_configUri(configUri),
_mutex(),
- _metricsHook(*this),
+ _metricsHook(std::make_unique<MetricsUpdateHook>(*this)),
_metricsEngine(std::make_unique<MetricsEngine>()),
- _fileHeaderContext(*this, progName),
+ _fileHeaderContext(progName),
_tls(),
_diskMemUsageSampler(),
_persistenceEngine(),
@@ -219,7 +233,6 @@ Proton::Proton(const config::ConfigUri & configUri,
_threadPool(128 * 1024),
_distributionKey(-1),
_isInitializing(true),
- _isReplayDone(false),
_abortInit(false),
_initStarted(false),
_initComplete(false),
@@ -260,7 +273,7 @@ Proton::init(const BootstrapConfig::SP & configSnapshot)
diskMemUsageSamplerConfig(protonConfig, hwInfo));
_tls = std::make_unique<TLS>(_configUri.createWithNewId(protonConfig.tlsconfigid), _fileHeaderContext);
- _metricsEngine->addMetricsHook(_metricsHook);
+ _metricsEngine->addMetricsHook(*_metricsHook);
_fileHeaderContext.setClusterName(protonConfig.clustername, protonConfig.basedir);
_matchEngine = std::make_unique<MatchEngine>(protonConfig.numsearcherthreads,
protonConfig.numthreadspersearch,
@@ -331,7 +344,6 @@ Proton::init(const BootstrapConfig::SP & configSnapshot)
_executor.sync();
waitForOnlineState();
- _isReplayDone = true;
_rpcHooks->set_online();
_flushEngine->start();
@@ -470,7 +482,7 @@ Proton::shutdown_config_fetching_and_state_exposing_components_once() noexcept
_customComponentBindToken.reset();
_stateServer.reset();
if (_metricsEngine) {
- _metricsEngine->removeMetricsHook(_metricsHook);
+ _metricsEngine->removeMetricsHook(*_metricsHook);
_metricsEngine->stop();
}
_has_shut_down_config_and_state_components = true;
@@ -714,7 +726,7 @@ updateExecutorMetrics(ExecutorMetrics &metrics,
}
void
-Proton::updateMetrics(const metrics::UpdateHook::MetricLockGuard &)
+Proton::updateMetrics(const metrics::MetricLockGuard &)
{
{
ContentProtonMetrics &metrics = _metricsEngine->root();
@@ -836,6 +848,7 @@ const vespalib::string DOCUMENT_DB = "documentdb";
const vespalib::string FLUSH_ENGINE = "flushengine";
const vespalib::string TLS_NAME = "tls";
const vespalib::string RESOURCE_USAGE = "resourceusage";
+const vespalib::string THREAD_POOLS = "threadpools";
struct StateExplorerProxy : vespalib::StateExplorer {
const StateExplorer &explorer;
@@ -881,8 +894,7 @@ Proton::get_state(const vespalib::slime::Inserter &, bool) const
std::vector<vespalib::string>
Proton::get_children_names() const
{
- std::vector<vespalib::string> names({DOCUMENT_DB, MATCH_ENGINE, FLUSH_ENGINE, TLS_NAME, RESOURCE_USAGE});
- return names;
+ return {DOCUMENT_DB, THREAD_POOLS, MATCH_ENGINE, FLUSH_ENGINE, TLS_NAME, RESOURCE_USAGE};
}
std::unique_ptr<vespalib::StateExplorer>
@@ -899,6 +911,13 @@ Proton::get_child(vespalib::stringref name) const
return std::make_unique<search::transactionlog::TransLogServerExplorer>(_tls->getTransLogServer());
} else if (name == RESOURCE_USAGE && _diskMemUsageSampler) {
return std::make_unique<ResourceUsageExplorer>(_diskMemUsageSampler->writeFilter());
+ } else if (name == THREAD_POOLS) {
+ return std::make_unique<ProtonThreadPoolsExplorer>(_sharedExecutor.get(),
+ (_matchEngine) ? &_matchEngine->get_executor() : nullptr,
+ (_summaryEngine) ? &_summaryEngine->get_executor() : nullptr,
+ (_flushEngine) ? &_flushEngine->get_executor() : nullptr,
+ &_executor,
+ _warmupExecutor.get());
}
return Explorer_UP(nullptr);
}
diff --git a/searchcore/src/vespa/searchcore/proton/server/proton.h b/searchcore/src/vespa/searchcore/proton/server/proton.h
index f88cd7bf0cd..2241389a63c 100644
--- a/searchcore/src/vespa/searchcore/proton/server/proton.h
+++ b/searchcore/src/vespa/searchcore/proton/server/proton.h
@@ -31,6 +31,7 @@
namespace vespalib { class StateServer; }
namespace search::transactionlog { class TransLogServerApp; }
+namespace metrics { class MetricLockGuard; }
namespace proton {
class DiskMemUsageSampler;
@@ -60,16 +61,6 @@ private:
using InitializeThreads = std::shared_ptr<vespalib::SyncableThreadExecutor>;
using BucketSpace = document::BucketSpace;
- struct MetricsUpdateHook : metrics::UpdateHook
- {
- Proton &self;
- MetricsUpdateHook(Proton &s)
- : metrics::UpdateHook("proton-hook"),
- self(s) {}
- void updateMetrics(const MetricLockGuard &guard) override { self.updateMetrics(guard); }
- };
- friend struct MetricsUpdateHook;
-
class ProtonFileHeaderContext : public search::common::FileHeaderContext
{
vespalib::string _hostName;
@@ -78,23 +69,23 @@ private:
pid_t _pid;
public:
- ProtonFileHeaderContext(const Proton &proton_, const vespalib::string &creator);
+ ProtonFileHeaderContext(const vespalib::string &creator);
~ProtonFileHeaderContext() override;
void addTags(vespalib::GenericHeader &header, const vespalib::string &name) const override;
void setClusterName(const vespalib::string &clusterName, const vespalib::string &baseDir);
};
- const config::ConfigUri _configUri;
- mutable std::shared_mutex _mutex;
- MetricsUpdateHook _metricsHook;
- std::unique_ptr<MetricsEngine> _metricsEngine;
- ProtonFileHeaderContext _fileHeaderContext;
- std::unique_ptr<TLS> _tls;
+ const config::ConfigUri _configUri;
+ mutable std::shared_mutex _mutex;
+ std::unique_ptr<metrics::UpdateHook> _metricsHook;
+ std::unique_ptr<MetricsEngine> _metricsEngine;
+ ProtonFileHeaderContext _fileHeaderContext;
+ std::unique_ptr<TLS> _tls;
std::unique_ptr<DiskMemUsageSampler> _diskMemUsageSampler;
PersistenceEngine::UP _persistenceEngine;
DocumentDBMap _documentDBMap;
- std::unique_ptr<MatchEngine> _matchEngine;
+ std::unique_ptr<MatchEngine> _matchEngine;
std::unique_ptr<SummaryEngine> _summaryEngine;
std::unique_ptr<DocsumBySlime> _docsumBySlime;
MemoryFlushConfigUpdater::UP _memoryFlushConfigUpdater;
@@ -138,12 +129,6 @@ private:
void applyConfig(const BootstrapConfig::SP & configSnapshot) override;
MonitorReply::UP ping(MonitorRequest::UP request, MonitorClient &client) override;
- /**
- * Called by the metrics update hook (typically in the context of
- * the metric manager). Do not call this function in multiple
- * threads at once.
- **/
- void updateMetrics(const metrics::UpdateHook::MetricLockGuard &guard);
void waitForInitDone();
void waitForOnlineState();
uint32_t getDistributionKey() const override { return _distributionKey; }
@@ -161,6 +146,13 @@ public:
~Proton() override;
/**
+ * Called by the metrics update hook (typically in the context of
+ * the metric manager). Do not call this function in multiple
+ * threads at once.
+ **/
+ void updateMetrics(const metrics::MetricLockGuard &guard);
+
+ /**
* This method must be called after the constructor and before the destructor.
* If not I will force a 'core' upon you.
* All relevant initialization is conducted here.
diff --git a/searchcore/src/vespa/searchcore/proton/server/proton_thread_pools_explorer.cpp b/searchcore/src/vespa/searchcore/proton/server/proton_thread_pools_explorer.cpp
new file mode 100644
index 00000000000..e0db9e29c35
--- /dev/null
+++ b/searchcore/src/vespa/searchcore/proton/server/proton_thread_pools_explorer.cpp
@@ -0,0 +1,43 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "executor_explorer_utils.h"
+#include "proton_thread_pools_explorer.h"
+#include <vespa/vespalib/data/slime/cursor.h>
+#include <vespa/vespalib/util/threadexecutor.h>
+
+using vespalib::SyncableThreadExecutor;
+
+namespace proton {
+
+using explorer::convert_executor_to_slime;
+
+ProtonThreadPoolsExplorer::ProtonThreadPoolsExplorer(const SyncableThreadExecutor* shared,
+ const SyncableThreadExecutor* match,
+ const SyncableThreadExecutor* docsum,
+ const SyncableThreadExecutor* flush,
+ const SyncableThreadExecutor* proton,
+ const SyncableThreadExecutor* warmup)
+ : _shared(shared),
+ _match(match),
+ _docsum(docsum),
+ _flush(flush),
+ _proton(proton),
+ _warmup(warmup)
+{
+}
+
+void
+ProtonThreadPoolsExplorer::get_state(const vespalib::slime::Inserter& inserter, bool full) const
+{
+ auto& object = inserter.insertObject();
+ if (full) {
+ convert_executor_to_slime(_shared, object.setObject("shared"));
+ convert_executor_to_slime(_match, object.setObject("match"));
+ convert_executor_to_slime(_docsum, object.setObject("docsum"));
+ convert_executor_to_slime(_flush, object.setObject("flush"));
+ convert_executor_to_slime(_proton, object.setObject("proton"));
+ convert_executor_to_slime(_warmup, object.setObject("warmup"));
+ }
+}
+
+}
diff --git a/searchcore/src/vespa/searchcore/proton/server/proton_thread_pools_explorer.h b/searchcore/src/vespa/searchcore/proton/server/proton_thread_pools_explorer.h
new file mode 100644
index 00000000000..8022a0483c4
--- /dev/null
+++ b/searchcore/src/vespa/searchcore/proton/server/proton_thread_pools_explorer.h
@@ -0,0 +1,35 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include <vespa/vespalib/net/state_explorer.h>
+
+namespace vespalib { class SyncableThreadExecutor; }
+
+namespace proton {
+
+/**
+ * Class used to explore the shared thread pools used by proton and it's document databases.
+ */
+class ProtonThreadPoolsExplorer : public vespalib::StateExplorer {
+private:
+ const vespalib::SyncableThreadExecutor* _shared;
+ const vespalib::SyncableThreadExecutor* _match;
+ const vespalib::SyncableThreadExecutor* _docsum;
+ const vespalib::SyncableThreadExecutor* _flush;
+ const vespalib::SyncableThreadExecutor* _proton;
+ const vespalib::SyncableThreadExecutor* _warmup;
+
+public:
+ ProtonThreadPoolsExplorer(const vespalib::SyncableThreadExecutor* shared,
+ const vespalib::SyncableThreadExecutor* match,
+ const vespalib::SyncableThreadExecutor* docsum,
+ const vespalib::SyncableThreadExecutor* flush,
+ const vespalib::SyncableThreadExecutor* proton,
+ const vespalib::SyncableThreadExecutor* warmup);
+
+ void get_state(const vespalib::slime::Inserter& inserter, bool full) const override;
+};
+
+}
+
diff --git a/searchcore/src/vespa/searchcore/proton/server/storeonlydocsubdb.cpp b/searchcore/src/vespa/searchcore/proton/server/storeonlydocsubdb.cpp
index 7d5d49b19c7..0bd50fc0104 100644
--- a/searchcore/src/vespa/searchcore/proton/server/storeonlydocsubdb.cpp
+++ b/searchcore/src/vespa/searchcore/proton/server/storeonlydocsubdb.cpp
@@ -120,7 +120,7 @@ StoreOnlyDocSubDB::StoreOnlyDocSubDB(const Config &cfg, const Context &ctx)
_pendingLidsForCommit(std::make_shared<PendingLidTracker>()),
_subDbId(cfg._subDbId),
_subDbType(cfg._subDbType),
- _fileHeaderContext(*this, ctx._fileHeaderContext, _docTypeName, _baseDir),
+ _fileHeaderContext(ctx._fileHeaderContext, _docTypeName, _baseDir),
_gidToLidChangeHandler(std::make_shared<DummyGidToLidChangeHandler>())
{
vespalib::mkdir(_baseDir, false); // Assume parent is created.
@@ -497,8 +497,7 @@ StoreOnlyDocSubDB::getDocumentDBReference()
}
StoreOnlySubDBFileHeaderContext::
-StoreOnlySubDBFileHeaderContext([[maybe_unused]] StoreOnlyDocSubDB &owner,
- const FileHeaderContext & parentFileHeaderContext,
+StoreOnlySubDBFileHeaderContext(const FileHeaderContext & parentFileHeaderContext,
const DocTypeName &docTypeName,
const vespalib::string &baseDir)
: FileHeaderContext(),
diff --git a/searchcore/src/vespa/searchcore/proton/server/storeonlydocsubdb.h b/searchcore/src/vespa/searchcore/proton/server/storeonlydocsubdb.h
index 1cdd22fcc41..7c3f7c82eb0 100644
--- a/searchcore/src/vespa/searchcore/proton/server/storeonlydocsubdb.h
+++ b/searchcore/src/vespa/searchcore/proton/server/storeonlydocsubdb.h
@@ -50,8 +50,6 @@ public:
void close() override { }
};
-class StoreOnlyDocSubDB;
-
/**
* File header context used by the store-only sub database.
*
@@ -65,8 +63,7 @@ class StoreOnlySubDBFileHeaderContext : public search::common::FileHeaderContext
vespalib::string _subDB;
public:
- StoreOnlySubDBFileHeaderContext(StoreOnlyDocSubDB &owner,
- const search::common::FileHeaderContext & parentFileHeaderContext,
+ StoreOnlySubDBFileHeaderContext(const search::common::FileHeaderContext & parentFileHeaderContext,
const DocTypeName &docTypeName,
const vespalib::string &baseDir);
~StoreOnlySubDBFileHeaderContext();
diff --git a/searchcore/src/vespa/searchcore/proton/summaryengine/summaryengine.h b/searchcore/src/vespa/searchcore/proton/summaryengine/summaryengine.h
index 029aefacfc8..c1cb1f91a2a 100644
--- a/searchcore/src/vespa/searchcore/proton/summaryengine/summaryengine.h
+++ b/searchcore/src/vespa/searchcore/proton/summaryengine/summaryengine.h
@@ -65,6 +65,11 @@ public:
vespalib::ThreadStackExecutor::Stats getExecutorStats() { return _executor.getStats(); }
/**
+ * Returns the underlying executor. Only used for state explorers.
+ */
+ const vespalib::SyncableThreadExecutor& get_executor() const { return _executor; }
+
+ /**
* Starts the underlying threads. This will throw a vespalib::Exception if
* it failed to start for any reason.
*/