@@ -13,42 +13,48 @@ open NBomber.Domain.DomainTypes
1313open NBomber.Domain .Stats .Statistics
1414
1515type ActorMessage =
16- | AddResponse of StepResponse
17- | AddResponses of StepResponse []
18- | PublishStatsToCoordinator
19- | GetRealtimeStats of reply : TaskCompletionSource<ScenarioStats> * LoadSimulationStats * duration : TimeSpan
20- | GetFinalStats of reply : TaskCompletionSource<ScenarioStats> * LoadSimulationStats * duration : TimeSpan
16+ | AddResponse of StepResponse
17+ | AddResponses of StepResponse list
18+ | GetRawStats of reply : TaskCompletionSource<ScenarioRawStats> * timestamp : TimeSpan
19+ | GetRealtimeStats of reply : TaskCompletionSource<ScenarioStats> * LoadSimulationStats * duration : TimeSpan
20+ | GetFinalStats of reply : TaskCompletionSource<ScenarioStats> * LoadSimulationStats * duration : TimeSpan
2121
2222type IScenarioStatsActor =
2323 abstract Publish: ActorMessage -> unit
24+ abstract GetRawStats: timestamp : TimeSpan -> Task < ScenarioRawStats >
2425 abstract GetRealtimeStats: LoadSimulationStats * duration : TimeSpan -> Task < ScenarioStats >
2526 abstract GetFinalStats: LoadSimulationStats * duration : TimeSpan -> Task < ScenarioStats >
2627
27- type ScenarioStatsActor ( logger : ILogger , scenario : Scenario , reportingInterval : TimeSpan ) =
28+ type ScenarioStatsActor ( logger : ILogger , scenario : Scenario , reportingInterval : TimeSpan , keepRawStats : bool ) =
2829
2930 let _allStepsData = Array.init scenario.Steps.Length ( fun _ -> StepStatsRawData.createEmpty())
3031 let mutable _intervalStepsData = Array.init scenario.Steps.Length ( fun _ -> StepStatsRawData.createEmpty())
32+ let mutable _intervalRawStats = List.empty
3133
32- let addResponse ( allData : StepStatsRawData []) ( intervalData : StepStatsRawData []) ( resp : StepResponse ) =
33- let allStData = allData.[ resp.StepIndex]
34- let intervalStData = intervalData.[ resp.StepIndex]
35- allData.[ resp.StepIndex] <- StepStatsRawData.addResponse allStData resp
36- intervalData.[ resp.StepIndex] <- StepStatsRawData.addResponse intervalStData resp
34+ let addResponse ( resp : StepResponse ) =
35+ let allStData = _ allStepsData.[ resp.StepIndex]
36+ let intervalStData = _ intervalStepsData.[ resp.StepIndex]
37+ _ allStepsData.[ resp.StepIndex] <- StepStatsRawData.addResponse allStData resp
38+ _ intervalStepsData.[ resp.StepIndex] <- StepStatsRawData.addResponse intervalStData resp
39+
40+ if keepRawStats then
41+ resp.ClientResponse.Payload <- null // to prevent sending in cluster mode
42+ resp.ClientResponse.Message <- null
43+ _ intervalRawStats <- resp :: _ intervalRawStats
3744
3845 let createScenarioStats ( stepsData , simulationStats , operation , duration , interval ) =
3946 ScenarioStats.create scenario stepsData simulationStats operation duration interval
4047
4148 let _actor = ActionBlock( fun msg ->
4249 try
4350 match msg with
44- | AddResponse response ->
45- addResponse _ allStepsData _ intervalStepsData response
46-
47- | AddResponses responses ->
48- responses |> Array.iter( addResponse _ allStepsData _ intervalStepsData)
51+ | AddResponse response -> addResponse response
52+ | AddResponses responses -> responses |> List.iter addResponse
4953
50- | PublishStatsToCoordinator ->
51- failwith " invalid operation" // it's only needed for cluster
54+ | GetRawStats ( reply, timestamp) ->
55+ let stats = { ScenarioName = scenario.ScenarioName; Data = _ intervalRawStats; Timestamp = timestamp }
56+ reply.TrySetResult( stats) |> ignore
57+ _ intervalRawStats <- List.empty
5258
5359 | GetRealtimeStats ( reply, simulationStats, duration) ->
5460 let scnStats = createScenarioStats(_ intervalStepsData, simulationStats, OperationType.Bombing, duration, reportingInterval)
@@ -60,23 +66,31 @@ type ScenarioStatsActor(logger: ILogger, scenario: Scenario, reportingInterval:
6066 let scnStats = createScenarioStats(_ allStepsData, simulationStats, OperationType.Complete, duration, duration)
6167 reply.TrySetResult( scnStats) |> ignore
6268 with
63- | ex -> logger.Error( ex , " GlobalScenarioStatsActor failed" )
69+ | ex -> logger.Error $ " {nameof ScenarioStatsActor} failed: {ex.ToString()} "
6470 )
6571
6672 interface IScenarioStatsActor with
6773
6874 [<MethodImpl( MethodImplOptions.AggressiveInlining) >]
6975 member _.Publish ( msg ) = _ actor.Post( msg) |> ignore
7076
77+ member _.GetRawStats ( timestamp ) =
78+ let reply = TaskCompletionSource< ScenarioRawStats>()
79+ GetRawStats( reply, timestamp) |> _ actor.Post |> ignore
80+ reply.Task
81+
7182 member _.GetRealtimeStats ( simulationStats , duration ) =
72- let tcs = TaskCompletionSource< ScenarioStats>()
73- GetRealtimeStats( tcs , simulationStats, duration) |> _ actor.Post |> ignore
74- tcs .Task
83+ let reply = TaskCompletionSource< ScenarioStats>()
84+ GetRealtimeStats( reply , simulationStats, duration) |> _ actor.Post |> ignore
85+ reply .Task
7586
7687 member _.GetFinalStats ( simulationStats , duration ) =
77- let tcs = TaskCompletionSource< ScenarioStats>()
78- GetFinalStats( tcs , simulationStats, duration) |> _ actor.Post |> ignore
79- tcs .Task
88+ let reply = TaskCompletionSource< ScenarioStats>()
89+ GetFinalStats( reply , simulationStats, duration) |> _ actor.Post |> ignore
90+ reply .Task
8091
8192let create ( logger : ILogger ) ( scenario : Scenario ) ( reportingInterval : TimeSpan ) =
82- ScenarioStatsActor( logger, scenario, reportingInterval) :> IScenarioStatsActor
93+ ScenarioStatsActor( logger, scenario, reportingInterval, keepRawStats = false ) :> IScenarioStatsActor
94+
95+ let createWithRawStats ( logger : ILogger ) ( scenario : Scenario ) ( reportingInterval : TimeSpan ) =
96+ ScenarioStatsActor( logger, scenario, reportingInterval, keepRawStats = true ) :> IScenarioStatsActor
0 commit comments