@@ -13,42 +13,48 @@ open NBomber.Domain.DomainTypes
13
13
open NBomber.Domain .Stats .Statistics
14
14
15
15
type 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
21
21
22
22
type IScenarioStatsActor =
23
23
abstract Publish: ActorMessage -> unit
24
+ abstract GetRawStats: timestamp : TimeSpan -> Task < ScenarioRawStats >
24
25
abstract GetRealtimeStats: LoadSimulationStats * duration : TimeSpan -> Task < ScenarioStats >
25
26
abstract GetFinalStats: LoadSimulationStats * duration : TimeSpan -> Task < ScenarioStats >
26
27
27
- type ScenarioStatsActor ( logger : ILogger , scenario : Scenario , reportingInterval : TimeSpan ) =
28
+ type ScenarioStatsActor ( logger : ILogger , scenario : Scenario , reportingInterval : TimeSpan , keepRawStats : bool ) =
28
29
29
30
let _allStepsData = Array.init scenario.Steps.Length ( fun _ -> StepStatsRawData.createEmpty())
30
31
let mutable _intervalStepsData = Array.init scenario.Steps.Length ( fun _ -> StepStatsRawData.createEmpty())
32
+ let mutable _intervalRawStats = List.empty
31
33
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
37
44
38
45
let createScenarioStats ( stepsData , simulationStats , operation , duration , interval ) =
39
46
ScenarioStats.create scenario stepsData simulationStats operation duration interval
40
47
41
48
let _actor = ActionBlock( fun msg ->
42
49
try
43
50
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
49
53
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
52
58
53
59
| GetRealtimeStats ( reply, simulationStats, duration) ->
54
60
let scnStats = createScenarioStats(_ intervalStepsData, simulationStats, OperationType.Bombing, duration, reportingInterval)
@@ -60,23 +66,31 @@ type ScenarioStatsActor(logger: ILogger, scenario: Scenario, reportingInterval:
60
66
let scnStats = createScenarioStats(_ allStepsData, simulationStats, OperationType.Complete, duration, duration)
61
67
reply.TrySetResult( scnStats) |> ignore
62
68
with
63
- | ex -> logger.Error( ex , " GlobalScenarioStatsActor failed" )
69
+ | ex -> logger.Error $ " {nameof ScenarioStatsActor} failed: {ex.ToString()} "
64
70
)
65
71
66
72
interface IScenarioStatsActor with
67
73
68
74
[<MethodImpl( MethodImplOptions.AggressiveInlining) >]
69
75
member _.Publish ( msg ) = _ actor.Post( msg) |> ignore
70
76
77
+ member _.GetRawStats ( timestamp ) =
78
+ let reply = TaskCompletionSource< ScenarioRawStats>()
79
+ GetRawStats( reply, timestamp) |> _ actor.Post |> ignore
80
+ reply.Task
81
+
71
82
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
75
86
76
87
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
80
91
81
92
let 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