move to event based enum for api

This commit is contained in:
Jaremy Creechley 2023-11-28 22:35:35 -07:00
parent 4b7d88f5de
commit d8361d53ac
No known key found for this signature in database
GPG Key ID: 4E66FB67B21D3300
3 changed files with 35 additions and 79 deletions

View File

@ -15,14 +15,8 @@ when chronosProfiling:
## Returns metrics for the current event loop.
result = futureMetrics
proc enableEventCallbacks*(): void =
onFutureEvent = handleFutureEventCB
onFutureExecEvent = handleFutureExecEventCB
proc setFutureEventCallback*(): void =
proc enableProfiling*() =
## Enables profiling on the current event loop.
if not isNil(handleFutureEvent): return
enableEventCallbacks()
handleFutureEvent = proc (e: Event) {.nimcall.} =
futureMetrics.processEvent(e)
onFutureEvent = metrics.handleFutureEvent

View File

@ -1,62 +0,0 @@
## This module defines the lower-level callback implementations that hook into
## the Chronos scheduler when profiling is enabled. The main goal is to provide
## timestamped events changes for futures while allowing a simpler implementation
## (only one event object type) for the remainder of the profiler.
import ".."/timer
import ".."/futures
import ".."/srcloc
type
ExtendedFutureState* {.pure.} = enum
Pending,
Running,
Paused,
Completed,
Cancelled,
Failed,
Event* = object
future: FutureBase
newState*: ExtendedFutureState
timestamp*: Moment
var handleFutureEvent* {.threadvar.}: proc (event: Event) {.nimcall, gcsafe, raises: [].}
proc `location`*(self: Event): SrcLoc =
self.future.internalLocation[Create][]
proc `futureId`*(self: Event): uint =
self.future.id
proc mkEvent(future: FutureBase, state: ExtendedFutureState): Event =
Event(
future: future,
newState: state,
timestamp: Moment.now(),
)
proc handleFutureEventCB*(future: FutureBase,
state: FutureState): void {.nimcall.} =
{.cast(gcsafe).}:
let extendedState = case state:
of FutureState.Pending: ExtendedFutureState.Pending
of FutureState.Completed: ExtendedFutureState.Completed
of FutureState.Cancelled: ExtendedFutureState.Cancelled
of FutureState.Failed: ExtendedFutureState.Failed
if not isNil(handleFutureEvent):
handleFutureEvent(mkEvent(future, extendedState))
proc handleFutureExecEventCB*(future: FutureBase,
state: FutureExecutionState): void {.nimcall.} =
{.cast(gcsafe).}:
let extendedState = case state:
of FutureExecutionState.Running: ExtendedFutureState.Running
of FutureExecutionState.Paused: ExtendedFutureState.Paused
if not isNil(handleFutureEvent):
handleFutureEvent(mkEvent(future, extendedState))

View File

@ -6,6 +6,33 @@ import ../[timer, srcloc]
export timer, tables, srcloc
type
Event* = object
futureId: uint
loc: SrcLoc
state: FutureState
event*: FutureExecutionEvent
timestamp*: Moment
proc processEvent*(self: var ProfilerMetrics, event: Event): void
proc handleFutureEvent*(future: FutureBase,
event: FutureExecutionEvent): void {.nimcall.} =
{.cast(gcsafe).}:
let extendedState = case state:
of Init: ExtendedFutureState.Pending
of Run: ExtendedFutureState.Running
of Pause: ExtendedFutureState.Paused
of Finish: future.internalState.toExtendedEvent()
processEvent Event(
future: future,
loc: future.internalLocation[Create][],
state: future.internalState,
event: event,
timestamp: Moment.now()
)
type
AggregateFutureMetrics* = object
execTime*: Duration
@ -119,14 +146,11 @@ proc futureCompleted(self: var ProfilerMetrics, event: Event): void =
self.partials.del(event.futureId)
proc processEvent*(self: var ProfilerMetrics, event: Event): void =
case event.newState:
of Pending: self.futureCreated(event)
of Running: self.futureRunning(event)
of Paused: self.futurePaused(event)
# Completion, failure and cancellation are currently handled the same way.
of Completed: self.futureCompleted(event)
of Failed: self.futureCompleted(event)
of Cancelled: self.futureCompleted(event)
case event.event:
of Init: self.futureCreated(event)
of Run: self.futureRunning(event)
of Pause: self.futurePaused(event)
of Finish: self.futureCompleted(event)
proc processAllEvents*(self: var ProfilerMetrics, events: seq[Event]): void =
for event in events: