mirror of
https://github.com/logos-storage/nim-chroprof.git
synced 2026-01-02 13:33:06 +00:00
67 lines
1.9 KiB
Nim
67 lines
1.9 KiB
Nim
import chronos
|
|
import ../chroprof/[api, events, profiler]
|
|
|
|
type SimpleEvent* = object
|
|
procedure*: string
|
|
state*: ExtendedFutureState
|
|
|
|
# XXX this is sort of bad cause we get global state all over, but the fact we
|
|
# can't use closures on callbacks and that callbacks themselves are just
|
|
# global vars means we can't really do much better for now.
|
|
var recording*: seq[SimpleEvent]
|
|
var rawRecording*: seq[Event]
|
|
var fakeTime*: Moment = Moment.init(0, 1.milliseconds)
|
|
|
|
proc recordEvent(event: Event) {.nimcall, gcsafe, raises: [].} =
|
|
{.cast(gcsafe).}:
|
|
recording.add(
|
|
SimpleEvent(procedure: $event.location.procedure, state: event.newState)
|
|
)
|
|
|
|
var timeShifted = event
|
|
timeShifted.timestamp = fakeTime
|
|
|
|
rawRecording.add(timeShifted)
|
|
|
|
proc recordSegment*(segment: string) =
|
|
{.cast(gcsafe).}:
|
|
recording.add(SimpleEvent(procedure: segment, state: ExtendedFutureState.Running))
|
|
|
|
proc stopRecording*(): void =
|
|
recording = @[]
|
|
rawRecording = @[]
|
|
detachMonitoring()
|
|
|
|
proc startRecording*() =
|
|
stopRecording()
|
|
attachMonitoring(recordEvent)
|
|
|
|
proc forProc*(self: var MetricsTotals, procedure: string): AggregateMetrics =
|
|
for (key, aggMetrics) in self.mpairs:
|
|
if key.procedure == procedure:
|
|
return aggMetrics
|
|
|
|
proc resetTime*() =
|
|
fakeTime = Moment.now()
|
|
|
|
proc advanceTime*(duration: Duration) =
|
|
fakeTime += duration
|
|
|
|
proc advanceTimeAsync*(duration: Duration): Future[void] =
|
|
# Simulates a non-blocking operation that takes the provided duration to
|
|
# complete.
|
|
var retFuture = newFuture[void]("advanceTimeAsync")
|
|
var timer: TimerCallback
|
|
|
|
proc completion(data: pointer) {.gcsafe.} =
|
|
if not (retFuture.finished()):
|
|
advanceTime(duration)
|
|
retFuture.complete()
|
|
|
|
# The actual value for the timer is irrelevant, the important thing is that
|
|
# this causes the parent to pause before we advance time.
|
|
timer =
|
|
setTimer(Moment.fromNow(10.milliseconds), completion, cast[pointer](retFuture))
|
|
|
|
return retFuture
|