1
- use criterion:: { Criterion , criterion_group, criterion_main} ;
1
+ use criterion:: { BatchSize , Criterion , criterion_group, criterion_main} ;
2
2
use futures_util:: StreamExt ;
3
- use std:: time:: Duration ;
3
+ use std:: {
4
+ sync:: { Arc , mpsc} ,
5
+ thread,
6
+ time:: Duration ,
7
+ } ;
4
8
use temporal_sdk:: { WfContext , WorkflowFunction } ;
5
- use temporal_sdk_core:: replay:: HistoryForReplay ;
9
+ use temporal_sdk_core:: { CoreRuntime , replay:: HistoryForReplay } ;
10
+ use temporal_sdk_core_api:: telemetry:: metrics:: {
11
+ MetricKeyValue , MetricParametersBuilder , NewAttributes ,
12
+ } ;
6
13
use temporal_sdk_core_protos:: DEFAULT_WORKFLOW_TYPE ;
7
- use temporal_sdk_core_test_utils:: { canned_histories, replay_sdk_worker} ;
14
+ use temporal_sdk_core_test_utils:: {
15
+ DONT_AUTO_INIT_INTEG_TELEM , canned_histories, prom_metrics, replay_sdk_worker,
16
+ } ;
8
17
9
18
pub fn criterion_benchmark ( c : & mut Criterion ) {
10
19
let tokio_runtime = tokio:: runtime:: Builder :: new_current_thread ( )
11
20
. enable_time ( )
12
21
. build ( )
13
22
. unwrap ( ) ;
14
23
let _g = tokio_runtime. enter ( ) ;
24
+ DONT_AUTO_INIT_INTEG_TELEM . set ( true ) ;
15
25
16
26
let num_timers = 10 ;
17
27
let t = canned_histories:: long_sequential_timers ( num_timers as usize ) ;
@@ -21,14 +31,17 @@ pub fn criterion_benchmark(c: &mut Criterion) {
21
31
) ;
22
32
23
33
c. bench_function ( "Small history replay" , |b| {
24
- b. iter ( || {
25
- tokio_runtime . block_on ( async {
34
+ b. to_async ( & tokio_runtime ) . iter_batched (
35
+ || {
26
36
let func = timers_wf ( num_timers) ;
27
- let mut worker = replay_sdk_worker ( [ hist. clone ( ) ] ) ;
37
+ ( func, replay_sdk_worker ( [ hist. clone ( ) ] ) )
38
+ } ,
39
+ |( func, mut worker) | async move {
28
40
worker. register_wf ( DEFAULT_WORKFLOW_TYPE , func) ;
29
41
worker. run ( ) . await . unwrap ( ) ;
30
- } )
31
- } )
42
+ } ,
43
+ BatchSize :: SmallInput ,
44
+ )
32
45
} ) ;
33
46
34
47
let num_tasks = 50 ;
@@ -39,18 +52,104 @@ pub fn criterion_benchmark(c: &mut Criterion) {
39
52
) ;
40
53
41
54
c. bench_function ( "Large payloads history replay" , |b| {
42
- b. iter ( || {
43
- tokio_runtime . block_on ( async {
55
+ b. to_async ( & tokio_runtime ) . iter_batched (
56
+ || {
44
57
let func = big_signals_wf ( num_tasks) ;
45
- let mut worker = replay_sdk_worker ( [ hist. clone ( ) ] ) ;
58
+ ( func, replay_sdk_worker ( [ hist. clone ( ) ] ) )
59
+ } ,
60
+ |( func, mut worker) | async move {
46
61
worker. register_wf ( DEFAULT_WORKFLOW_TYPE , func) ;
47
62
worker. run ( ) . await . unwrap ( ) ;
48
- } )
49
- } )
63
+ } ,
64
+ BatchSize :: SmallInput ,
65
+ )
50
66
} ) ;
51
67
}
52
68
53
- criterion_group ! ( benches, criterion_benchmark) ;
69
+ pub fn bench_metrics ( c : & mut Criterion ) {
70
+ DONT_AUTO_INIT_INTEG_TELEM . set ( true ) ;
71
+ let tokio_runtime = tokio:: runtime:: Builder :: new_current_thread ( )
72
+ . enable_all ( )
73
+ . build ( )
74
+ . unwrap ( ) ;
75
+ let _tokio = tokio_runtime. enter ( ) ;
76
+ let ( mut telemopts, addr, _aborter) = prom_metrics ( None ) ;
77
+ telemopts. logging = None ;
78
+ let rt = CoreRuntime :: new_assume_tokio ( telemopts) . unwrap ( ) ;
79
+ let meter = rt. telemetry ( ) . get_metric_meter ( ) . unwrap ( ) ;
80
+
81
+ c. bench_function ( "Record with new attributes on each call" , move |b| {
82
+ b. iter_batched (
83
+ || {
84
+ let c = meter. counter (
85
+ MetricParametersBuilder :: default ( )
86
+ . name ( "c" )
87
+ . build ( )
88
+ . unwrap ( ) ,
89
+ ) ;
90
+ let h = meter. histogram (
91
+ MetricParametersBuilder :: default ( )
92
+ . name ( "h" )
93
+ . build ( )
94
+ . unwrap ( ) ,
95
+ ) ;
96
+ let g = meter. gauge (
97
+ MetricParametersBuilder :: default ( )
98
+ . name ( "g" )
99
+ . build ( )
100
+ . unwrap ( ) ,
101
+ ) ;
102
+
103
+ let vals = [ 1 , 2 , 3 , 4 , 5 ] ;
104
+ let labels = [ "l1" , "l2" ] ;
105
+
106
+ let ( start_tx, start_rx) = mpsc:: channel ( ) ;
107
+ let start_rx = Arc :: new ( std:: sync:: Mutex :: new ( start_rx) ) ;
108
+
109
+ let mut thread_handles = Vec :: new ( ) ;
110
+ for _ in 0 ..3 {
111
+ let c = c. clone ( ) ;
112
+ let h = h. clone ( ) ;
113
+ let g = g. clone ( ) ;
114
+ let meter = meter. clone ( ) ;
115
+ let start_rx = start_rx. clone ( ) ;
116
+
117
+ let handle = thread:: spawn ( move || {
118
+ // Wait for start signal
119
+ let _ = start_rx. lock ( ) . unwrap ( ) . recv ( ) ;
120
+
121
+ for _ in 1 ..=100 {
122
+ for & val in & vals {
123
+ for & label in & labels {
124
+ let attribs = meter. new_attributes ( NewAttributes :: from ( vec ! [
125
+ MetricKeyValue :: new( "label" , label) ,
126
+ ] ) ) ;
127
+ c. add ( val, & attribs) ;
128
+ h. record ( val, & attribs) ;
129
+ g. record ( val, & attribs) ;
130
+ }
131
+ }
132
+ }
133
+ } ) ;
134
+ thread_handles. push ( handle) ;
135
+ }
136
+
137
+ ( start_tx, thread_handles)
138
+ } ,
139
+ |( start_tx, thread_handles) | {
140
+ for _ in 0 ..3 {
141
+ let _ = start_tx. send ( ( ) ) ;
142
+ }
143
+ for handle in thread_handles {
144
+ let _ = handle. join ( ) ;
145
+ }
146
+ } ,
147
+ BatchSize :: SmallInput ,
148
+ )
149
+ } ) ;
150
+ }
151
+
152
+ criterion_group ! ( benches, criterion_benchmark, bench_metrics) ;
54
153
criterion_main ! ( benches) ;
55
154
56
155
fn timers_wf ( num_timers : u32 ) -> WorkflowFunction {
0 commit comments