phase 2 progress
This commit is contained in:
@@ -166,17 +166,6 @@ void ControlServices::ConsumeCompletedOscCommits(std::vector<CompletedOscCommit>
|
||||
completedCommits.swap(mCompletedOscCommits);
|
||||
}
|
||||
|
||||
void ControlServices::ConsumeRuntimeCoordinatorResults(std::vector<RuntimeCoordinatorServiceResult>& results)
|
||||
{
|
||||
results.clear();
|
||||
|
||||
std::lock_guard<std::mutex> lock(mRuntimeCoordinatorResultMutex);
|
||||
if (mRuntimeCoordinatorResults.empty())
|
||||
return;
|
||||
|
||||
results.swap(mRuntimeCoordinatorResults);
|
||||
}
|
||||
|
||||
void ControlServices::StartPolling(RuntimeCoordinator& runtimeCoordinator)
|
||||
{
|
||||
if (mPollRunning.exchange(true))
|
||||
@@ -218,7 +207,6 @@ void ControlServices::PollLoop(RuntimeCoordinator& runtimeCoordinator)
|
||||
completedCommit.generation = entry.second.generation;
|
||||
std::lock_guard<std::mutex> lock(mCompletedOscCommitMutex);
|
||||
mCompletedOscCommits.push_back(std::move(completedCommit));
|
||||
QueueRuntimeCoordinatorResult(result);
|
||||
}
|
||||
else if (!result.errorMessage.empty())
|
||||
{
|
||||
@@ -228,8 +216,8 @@ void ControlServices::PollLoop(RuntimeCoordinator& runtimeCoordinator)
|
||||
|
||||
bool registryChanged = false;
|
||||
const RuntimeCoordinatorResult pollResult = runtimeCoordinator.PollRuntimeStoreChanges(registryChanged);
|
||||
if (pollResult.runtimeStateBroadcastRequired || pollResult.shaderBuildRequested || pollResult.compileStatusChanged)
|
||||
QueueRuntimeCoordinatorResult(pollResult, pollResult.compileStatusChanged && !pollResult.compileStatusSucceeded && !pollResult.compileStatusMessage.empty());
|
||||
if (pollResult.compileStatusChanged && !pollResult.compileStatusSucceeded && !pollResult.compileStatusMessage.empty())
|
||||
OutputDebugStringA(("Runtime poll failed: " + pollResult.compileStatusMessage + "\n").c_str());
|
||||
|
||||
std::unique_lock<std::mutex> wakeLock(mPollWakeMutex);
|
||||
mPollWakeCondition.wait_for(wakeLock, kCompatibilityPollFallbackInterval, [this]() {
|
||||
@@ -248,16 +236,6 @@ void ControlServices::WakePolling()
|
||||
mPollWakeCondition.notify_one();
|
||||
}
|
||||
|
||||
void ControlServices::QueueRuntimeCoordinatorResult(const RuntimeCoordinatorResult& result, bool failed)
|
||||
{
|
||||
RuntimeCoordinatorServiceResult serviceResult;
|
||||
serviceResult.result = result;
|
||||
serviceResult.failed = failed;
|
||||
|
||||
std::lock_guard<std::mutex> lock(mRuntimeCoordinatorResultMutex);
|
||||
mRuntimeCoordinatorResults.push_back(std::move(serviceResult));
|
||||
}
|
||||
|
||||
void ControlServices::PublishRuntimeStateBroadcastRequested(const std::string& reason)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -20,12 +20,6 @@ class OscServer;
|
||||
class RuntimeEventDispatcher;
|
||||
class RuntimeStore;
|
||||
|
||||
struct RuntimeCoordinatorServiceResult
|
||||
{
|
||||
RuntimeCoordinatorResult result;
|
||||
bool failed = false;
|
||||
};
|
||||
|
||||
class ControlServices
|
||||
{
|
||||
public:
|
||||
@@ -56,7 +50,6 @@ public:
|
||||
bool QueueOscCommit(const std::string& routeKey, const std::string& layerKey, const std::string& parameterKey, const JsonValue& value, uint64_t generation, std::string& error);
|
||||
void ClearOscState();
|
||||
void ConsumeCompletedOscCommits(std::vector<CompletedOscCommit>& completedCommits);
|
||||
void ConsumeRuntimeCoordinatorResults(std::vector<RuntimeCoordinatorServiceResult>& results);
|
||||
|
||||
private:
|
||||
struct PendingOscUpdate
|
||||
@@ -79,7 +72,6 @@ private:
|
||||
void StopPolling();
|
||||
void PollLoop(RuntimeCoordinator& runtimeCoordinator);
|
||||
void WakePolling();
|
||||
void QueueRuntimeCoordinatorResult(const RuntimeCoordinatorResult& result, bool failed = false);
|
||||
void PublishRuntimeStateBroadcastRequested(const std::string& reason);
|
||||
void PublishOscValueReceived(const PendingOscUpdate& update, const std::string& routeKey);
|
||||
void PublishOscCommitRequested(const PendingOscCommit& commit);
|
||||
@@ -92,8 +84,6 @@ private:
|
||||
std::mutex mPollWakeMutex;
|
||||
std::condition_variable mPollWakeCondition;
|
||||
bool mPollWakeRequested = false;
|
||||
std::mutex mRuntimeCoordinatorResultMutex;
|
||||
std::vector<RuntimeCoordinatorServiceResult> mRuntimeCoordinatorResults;
|
||||
std::mutex mPendingOscMutex;
|
||||
std::map<std::string, PendingOscUpdate> mPendingOscUpdates;
|
||||
std::mutex mPendingOscCommitMutex;
|
||||
|
||||
@@ -78,14 +78,3 @@ void RuntimeServices::ConsumeCompletedOscCommits(std::vector<CompletedOscCommit>
|
||||
|
||||
mControlServices->ConsumeCompletedOscCommits(completedCommits);
|
||||
}
|
||||
|
||||
void RuntimeServices::ConsumeRuntimeCoordinatorResults(std::vector<RuntimeCoordinatorServiceResult>& results)
|
||||
{
|
||||
if (!mControlServices)
|
||||
{
|
||||
results.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
mControlServices->ConsumeRuntimeCoordinatorResults(results);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ public:
|
||||
bool QueueOscCommit(const std::string& routeKey, const std::string& layerKey, const std::string& parameterKey, const JsonValue& value, uint64_t generation, std::string& error);
|
||||
void ClearOscState();
|
||||
void ConsumeCompletedOscCommits(std::vector<CompletedOscCommit>& completedCommits);
|
||||
void ConsumeRuntimeCoordinatorResults(std::vector<RuntimeCoordinatorServiceResult>& results);
|
||||
|
||||
private:
|
||||
std::unique_ptr<ControlServices> mControlServices;
|
||||
|
||||
@@ -300,7 +300,7 @@ bool OpenGLComposite::RequestScreenshot(std::string& error)
|
||||
|
||||
void OpenGLComposite::renderEffect()
|
||||
{
|
||||
if (mRuntimeUpdateController && ProcessRuntimeServiceResults())
|
||||
if (mRuntimeUpdateController)
|
||||
mRuntimeUpdateController->ProcessRuntimeWork();
|
||||
std::vector<RuntimeServices::AppliedOscUpdate> appliedOscUpdates;
|
||||
std::vector<RuntimeServices::CompletedOscCommit> completedOscCommits;
|
||||
@@ -369,25 +369,6 @@ void OpenGLComposite::renderEffect()
|
||||
historyCap);
|
||||
}
|
||||
|
||||
bool OpenGLComposite::ProcessRuntimeServiceResults()
|
||||
{
|
||||
if (!mRuntimeServices || !mRuntimeUpdateController)
|
||||
return true;
|
||||
|
||||
bool shaderBuildRequested = false;
|
||||
std::vector<RuntimeCoordinatorServiceResult> serviceResults;
|
||||
mRuntimeServices->ConsumeRuntimeCoordinatorResults(serviceResults);
|
||||
for (const RuntimeCoordinatorServiceResult& serviceResult : serviceResults)
|
||||
{
|
||||
shaderBuildRequested = shaderBuildRequested || serviceResult.result.shaderBuildRequested;
|
||||
mRuntimeUpdateController->ApplyRuntimeCoordinatorResult(serviceResult.result);
|
||||
if (serviceResult.failed)
|
||||
return false;
|
||||
}
|
||||
|
||||
return !shaderBuildRequested;
|
||||
}
|
||||
|
||||
void OpenGLComposite::ProcessScreenshotRequest()
|
||||
{
|
||||
if (!mScreenshotRequested.exchange(false))
|
||||
|
||||
@@ -87,7 +87,6 @@ private:
|
||||
|
||||
bool InitOpenGLState();
|
||||
void renderEffect();
|
||||
bool ProcessRuntimeServiceResults();
|
||||
void ProcessScreenshotRequest();
|
||||
std::filesystem::path BuildScreenshotPath() const;
|
||||
};
|
||||
|
||||
@@ -45,6 +45,9 @@ RuntimeUpdateController::RuntimeUpdateController(
|
||||
mRuntimeEventDispatcher.Subscribe(
|
||||
RuntimeEventType::RuntimeStateBroadcastRequested,
|
||||
[this](const RuntimeEvent& event) { HandleRuntimeStateBroadcastRequested(event); });
|
||||
mRuntimeEventDispatcher.Subscribe(
|
||||
RuntimeEventType::RuntimeReloadRequested,
|
||||
[this](const RuntimeEvent& event) { HandleRuntimeReloadRequested(event); });
|
||||
mRuntimeEventDispatcher.Subscribe(
|
||||
RuntimeEventType::ShaderBuildRequested,
|
||||
[this](const RuntimeEvent& event) { HandleShaderBuildRequested(event); });
|
||||
@@ -137,6 +140,15 @@ void RuntimeUpdateController::HandleRuntimeStateBroadcastRequested(const Runtime
|
||||
mRuntimeServices.BroadcastState();
|
||||
}
|
||||
|
||||
void RuntimeUpdateController::HandleRuntimeReloadRequested(const RuntimeEvent& event)
|
||||
{
|
||||
const RuntimeReloadRequestedEvent* payload = std::get_if<RuntimeReloadRequestedEvent>(&event.payload);
|
||||
if (!payload)
|
||||
return;
|
||||
|
||||
mRuntimeStore.ClearReloadRequest();
|
||||
}
|
||||
|
||||
void RuntimeUpdateController::HandleShaderBuildRequested(const RuntimeEvent& event)
|
||||
{
|
||||
const ShaderBuildEvent* payload = std::get_if<ShaderBuildEvent>(&event.payload);
|
||||
@@ -317,16 +329,19 @@ void RuntimeUpdateController::PublishRuntimeEventHealthObservations(const Runtim
|
||||
{
|
||||
const RuntimeEventQueueMetrics queueMetrics = mRuntimeEventDispatcher.GetQueueMetrics();
|
||||
if (queueMetrics.depth != mLastReportedRuntimeEventQueueDepth ||
|
||||
queueMetrics.droppedCount != mLastReportedRuntimeEventDroppedCount)
|
||||
queueMetrics.droppedCount != mLastReportedRuntimeEventDroppedCount ||
|
||||
queueMetrics.coalescedCount != mLastReportedRuntimeEventCoalescedCount)
|
||||
{
|
||||
QueueDepthChangedEvent queueDepth;
|
||||
queueDepth.queueName = "runtime-events";
|
||||
queueDepth.depth = queueMetrics.depth;
|
||||
queueDepth.capacity = queueMetrics.capacity;
|
||||
queueDepth.droppedCount = queueMetrics.droppedCount;
|
||||
queueDepth.coalescedCount = queueMetrics.coalescedCount;
|
||||
mRuntimeEventDispatcher.PublishPayload(queueDepth, "HealthTelemetry");
|
||||
mLastReportedRuntimeEventQueueDepth = queueMetrics.depth;
|
||||
mLastReportedRuntimeEventDroppedCount = queueMetrics.droppedCount;
|
||||
mLastReportedRuntimeEventCoalescedCount = queueMetrics.coalescedCount;
|
||||
}
|
||||
|
||||
if (result.handlerInvocations == 0 && result.handlerFailures == 0)
|
||||
|
||||
@@ -35,6 +35,7 @@ public:
|
||||
|
||||
private:
|
||||
void HandleRuntimeStateBroadcastRequested(const RuntimeEvent& event);
|
||||
void HandleRuntimeReloadRequested(const RuntimeEvent& event);
|
||||
void HandleShaderBuildRequested(const RuntimeEvent& event);
|
||||
void HandleShaderBuildPrepared(const RuntimeEvent& event);
|
||||
void HandleShaderBuildFailed(const RuntimeEvent& event);
|
||||
@@ -64,4 +65,5 @@ private:
|
||||
std::size_t mPendingCoordinatorRenderResetEvents = 0;
|
||||
std::size_t mLastReportedRuntimeEventQueueDepth = static_cast<std::size_t>(-1);
|
||||
std::size_t mLastReportedRuntimeEventDroppedCount = static_cast<std::size_t>(-1);
|
||||
std::size_t mLastReportedRuntimeEventCoalescedCount = static_cast<std::size_t>(-1);
|
||||
};
|
||||
|
||||
@@ -246,6 +246,7 @@ RuntimeCoordinatorResult RuntimeCoordinator::LoadStackPreset(const std::string&
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::RequestShaderReload(bool preserveFeedbackState)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
PublishManualReloadRequested(preserveFeedbackState, "RequestShaderReload");
|
||||
RuntimeCoordinatorResult result = BuildQueuedReloadResult(preserveFeedbackState);
|
||||
PublishCoordinatorFollowUpEvents("RequestShaderReload", result);
|
||||
return result;
|
||||
@@ -266,6 +267,7 @@ RuntimeCoordinatorResult RuntimeCoordinator::PollRuntimeStoreChanges(bool& regis
|
||||
|
||||
if (reloadRequested)
|
||||
{
|
||||
PublishFileChangeDetected("PollRuntimeStoreChanges", registryChanged, reloadRequested);
|
||||
RuntimeCoordinatorResult result = BuildQueuedReloadResult(false);
|
||||
PublishCoordinatorFollowUpEvents("PollRuntimeStoreChanges", result);
|
||||
return result;
|
||||
@@ -273,6 +275,7 @@ RuntimeCoordinatorResult RuntimeCoordinator::PollRuntimeStoreChanges(bool& regis
|
||||
|
||||
if (registryChanged)
|
||||
{
|
||||
PublishFileChangeDetected("PollRuntimeStoreChanges", registryChanged, reloadRequested);
|
||||
RuntimeCoordinatorResult result = BuildAcceptedNoReloadResult();
|
||||
PublishCoordinatorFollowUpEvents("PollRuntimeStoreChanges", result);
|
||||
return result;
|
||||
@@ -332,6 +335,7 @@ RuntimeCoordinatorResult RuntimeCoordinator::HandlePreparedShaderBuildSuccess()
|
||||
RuntimeCoordinatorResult RuntimeCoordinator::HandleRuntimeReloadRequest()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
PublishManualReloadRequested(false, "HandleRuntimeReloadRequest");
|
||||
RuntimeCoordinatorResult result = BuildQueuedReloadResult(false);
|
||||
PublishCoordinatorFollowUpEvents("HandleRuntimeReloadRequest", result);
|
||||
return result;
|
||||
@@ -493,6 +497,36 @@ RuntimeCoordinatorResult RuntimeCoordinator::BuildAcceptedNoReloadResult() const
|
||||
return result;
|
||||
}
|
||||
|
||||
void RuntimeCoordinator::PublishFileChangeDetected(const std::string& reason, bool registryChanged, bool reloadRequested) const
|
||||
{
|
||||
try
|
||||
{
|
||||
FileChangeDetectedEvent event;
|
||||
event.path = reason;
|
||||
event.shaderPackageCandidate = registryChanged || reloadRequested;
|
||||
event.runtimeConfigCandidate = false;
|
||||
event.presetCandidate = false;
|
||||
mRuntimeEventDispatcher.PublishPayload(event, "RuntimeCoordinator");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeCoordinator::PublishManualReloadRequested(bool preserveFeedbackState, const std::string& reason) const
|
||||
{
|
||||
try
|
||||
{
|
||||
ManualReloadRequestedEvent event;
|
||||
event.preserveFeedbackState = preserveFeedbackState;
|
||||
event.reason = reason;
|
||||
mRuntimeEventDispatcher.PublishPayload(event, "RuntimeCoordinator");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeCoordinator::PublishCoordinatorResult(const std::string& action, const RuntimeCoordinatorResult& result) const
|
||||
{
|
||||
try
|
||||
|
||||
@@ -93,6 +93,8 @@ private:
|
||||
RuntimeCoordinatorResult ApplyStoreMutation(bool succeeded, const std::string& errorMessage, bool reloadRequired, bool preserveFeedbackState, bool persistenceRequested);
|
||||
RuntimeCoordinatorResult BuildQueuedReloadResult(bool preserveFeedbackState);
|
||||
RuntimeCoordinatorResult BuildAcceptedNoReloadResult() const;
|
||||
void PublishFileChangeDetected(const std::string& reason, bool registryChanged, bool reloadRequested) const;
|
||||
void PublishManualReloadRequested(bool preserveFeedbackState, const std::string& reason) const;
|
||||
void PublishCoordinatorResult(const std::string& action, const RuntimeCoordinatorResult& result) const;
|
||||
void PublishCoordinatorFollowUpEvents(const std::string& action, const RuntimeCoordinatorResult& result) const;
|
||||
|
||||
|
||||
@@ -29,6 +29,17 @@ inline std::string RuntimeEventDefaultCoalescingKey(const RuntimeEvent& event)
|
||||
return std::string(RuntimeEventTypeName(event.type)) + ":" + payload->routeKey;
|
||||
if (const auto* payload = std::get_if<FileChangeDetectedEvent>(&event.payload))
|
||||
return std::string(RuntimeEventTypeName(event.type)) + ":" + payload->path;
|
||||
if (const auto* payload = std::get_if<ShaderBuildEvent>(&event.payload))
|
||||
return std::string(RuntimeEventTypeName(event.type)) + ":" +
|
||||
std::to_string(payload->inputWidth) + "x" +
|
||||
std::to_string(payload->inputHeight) + ":" +
|
||||
(payload->preserveFeedbackState ? "preserve" : "reset");
|
||||
if (const auto* payload = std::get_if<RenderSnapshotPublishRequestedEvent>(&event.payload))
|
||||
return std::string(RuntimeEventTypeName(event.type)) + ":" +
|
||||
std::to_string(payload->outputWidth) + "x" +
|
||||
std::to_string(payload->outputHeight);
|
||||
if (const auto* payload = std::get_if<TimingSampleRecordedEvent>(&event.payload))
|
||||
return std::string(RuntimeEventTypeName(event.type)) + ":" + payload->subsystem + ":" + payload->metric;
|
||||
if (const auto* payload = std::get_if<QueueDepthChangedEvent>(&event.payload))
|
||||
return std::string(RuntimeEventTypeName(event.type)) + ":" + payload->queueName;
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "RuntimeEventCoalescingQueue.h"
|
||||
#include "RuntimeEventQueue.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
@@ -22,7 +24,8 @@ public:
|
||||
using Handler = std::function<void(const RuntimeEvent&)>;
|
||||
|
||||
explicit RuntimeEventDispatcher(std::size_t queueCapacity = 1024) :
|
||||
mQueue(queueCapacity)
|
||||
mQueue(queueCapacity),
|
||||
mCoalescingQueue(queueCapacity)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -34,6 +37,9 @@ public:
|
||||
if (event.sequence == 0)
|
||||
event.sequence = mNextSequence.fetch_add(1);
|
||||
|
||||
if (ShouldCoalesce(event))
|
||||
return mCoalescingQueue.Push(std::move(event));
|
||||
|
||||
return mQueue.Push(std::move(event));
|
||||
}
|
||||
|
||||
@@ -59,6 +65,7 @@ public:
|
||||
{
|
||||
const auto startedAt = std::chrono::steady_clock::now();
|
||||
RuntimeEventDispatchResult result;
|
||||
FlushCoalescedToFifo(maxEvents);
|
||||
std::vector<RuntimeEvent> events = mQueue.Drain(maxEvents);
|
||||
result.dispatchedEvents = events.size();
|
||||
|
||||
@@ -92,15 +99,56 @@ public:
|
||||
|
||||
RuntimeEventQueueMetrics GetQueueMetrics(std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now()) const
|
||||
{
|
||||
return mQueue.GetMetrics(now);
|
||||
RuntimeEventQueueMetrics metrics = mQueue.GetMetrics(now);
|
||||
const RuntimeEventCoalescingQueueMetrics coalescingMetrics = mCoalescingQueue.GetMetrics(now);
|
||||
if (metrics.depth == 0)
|
||||
metrics.oldestEventAgeMilliseconds = coalescingMetrics.oldestEventAgeMilliseconds;
|
||||
else if (coalescingMetrics.depth > 0)
|
||||
metrics.oldestEventAgeMilliseconds = (std::max)(metrics.oldestEventAgeMilliseconds, coalescingMetrics.oldestEventAgeMilliseconds);
|
||||
metrics.depth += coalescingMetrics.depth;
|
||||
metrics.capacity += coalescingMetrics.capacity;
|
||||
metrics.droppedCount += coalescingMetrics.droppedCount;
|
||||
metrics.coalescedCount = coalescingMetrics.coalescedCount;
|
||||
return metrics;
|
||||
}
|
||||
|
||||
std::size_t QueueDepth() const
|
||||
{
|
||||
return mQueue.Depth();
|
||||
return mQueue.Depth() + mCoalescingQueue.Depth();
|
||||
}
|
||||
|
||||
private:
|
||||
static bool ShouldCoalesce(const RuntimeEvent& event)
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case RuntimeEventType::OscValueReceived:
|
||||
case RuntimeEventType::OscCommitRequested:
|
||||
case RuntimeEventType::RuntimeStateBroadcastRequested:
|
||||
case RuntimeEventType::FileChangeDetected:
|
||||
case RuntimeEventType::RuntimeReloadRequested:
|
||||
case RuntimeEventType::ShaderBuildRequested:
|
||||
case RuntimeEventType::RenderSnapshotPublishRequested:
|
||||
case RuntimeEventType::TimingSampleRecorded:
|
||||
case RuntimeEventType::QueueDepthChanged:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void FlushCoalescedToFifo(std::size_t maxEvents)
|
||||
{
|
||||
const std::size_t fifoDepth = mQueue.Depth();
|
||||
if (maxEvents != 0 && fifoDepth >= maxEvents)
|
||||
return;
|
||||
|
||||
const std::size_t flushLimit = maxEvents == 0 ? 0 : maxEvents - fifoDepth;
|
||||
std::vector<RuntimeEvent> events = mCoalescingQueue.Drain(flushLimit);
|
||||
for (RuntimeEvent& event : events)
|
||||
mQueue.Push(std::move(event));
|
||||
}
|
||||
|
||||
std::vector<Handler> HandlersFor(RuntimeEventType type) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mHandlerMutex);
|
||||
@@ -114,6 +162,7 @@ private:
|
||||
}
|
||||
|
||||
RuntimeEventQueue mQueue;
|
||||
RuntimeEventCoalescingQueue mCoalescingQueue;
|
||||
std::atomic<uint64_t> mNextSequence{ 1 };
|
||||
mutable std::mutex mHandlerMutex;
|
||||
std::map<RuntimeEventType, std::vector<Handler>> mHandlers;
|
||||
|
||||
@@ -13,6 +13,7 @@ struct RuntimeEventQueueMetrics
|
||||
std::size_t depth = 0;
|
||||
std::size_t capacity = 0;
|
||||
std::size_t droppedCount = 0;
|
||||
std::size_t coalescedCount = 0;
|
||||
double oldestEventAgeMilliseconds = 0.0;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user