Draft implementation for Chronos thread freeze guard.

This commit is contained in:
ThatBen 2025-05-07 16:42:21 +02:00
parent 95da0353d2
commit cd4a3adfb1
No known key found for this signature in database
GPG Key ID: E020A7DDCD52E1AB
3 changed files with 15 additions and 5 deletions

View File

@ -7,11 +7,11 @@ export
var profilerInstance {.threadvar.}: ProfilerState
proc getMetrics*(): MetricsTotals =
## Returns the `MetricsTotals` for the event loop running in the
## Returns the `MetricsTotals` for the event loop running in the
## current thread.
result = profilerInstance.metrics
template enableProfiling*(callback: EventCallback) =
template enableProfiling*(callback: EventCallback, maxExecThreshold: Duration) =
## Enables profiling for the the event loop running in the current thread.
## The client may optionally supply a callback to be notified of `Future`
## events.
@ -19,10 +19,14 @@ template enableProfiling*(callback: EventCallback) =
proc(e: Event) {.nimcall, gcsafe, raises: [].} =
profilerInstance.processEvent(e)
callback(e)
,
maxExecThreshold = maxExecThreshold
)
template enableProfiling*() =
template enableProfiling*(maxExecThreshold: Duration) =
attachMonitoring(
proc(e: Event) {.nimcall, gcsafe, raises: [].} =
profilerInstance.processEvent(e)
,
maxExecThreshold = maxExecThreshold
)

View File

@ -1,4 +1,4 @@
## Metrics collector which allows exporting Chronos profiling metrics to
## Metrics collector which allows exporting Chronos profiling metrics to
## Prometheus.
import std/algorithm
@ -173,7 +173,7 @@ when defined(metrics):
var asyncProfilerInfo* {.global.}: ChronosProfilerInfo
proc enableProfilerMetrics*(k: int) =
proc enableProfilerMetrics*(k: int, maxExecThreshold: Duration) =
assert threadId() == moduleInitThread,
"You cannot call enableProfilerMetrics() from a thread other than" &
" the one that initialized the metricscolletor module."
@ -193,4 +193,6 @@ when defined(metrics):
{.cast(gcsafe).}:
if e.newState == ExtendedFutureState.Completed:
asyncProfilerInfo.collect()
,
maxExecThreshold = maxExecThreshold
)

View File

@ -142,6 +142,10 @@ proc aggregatePartial(
self.metrics.withValue(metrics.futureType, aggMetrics):
let execTime = metrics.partialExecTime - metrics.partialChildrenExecOverlap
if execTime > threshold:
raiseAssert("Execution time of future is too high (" &
$metrics.futureType & ")" & $execTime)
aggMetrics.callCount.inc()
aggMetrics.execTime += execTime
aggMetrics.execTimeMax = max(aggMetrics.execTimeMax, execTime)