8
8
"time"
9
9
10
10
"github.com/FZambia/tarantool"
11
- "github.com/tarantool/cartridge-cli/cli/common"
12
11
"github.com/tarantool/cartridge-cli/cli/context"
13
12
)
14
13
@@ -22,14 +21,25 @@ func printResults(results Results) {
22
21
fmt .Printf ("\t Requests per second: %d\n \n " , results .requestsPerSecond )
23
22
}
24
23
24
+ // verifyOperationsPercentage checks that the amount of operations percentage is 100.
25
+ func verifyOperationsPercentage (ctx * context.BenchCtx ) error {
26
+ entire_percentage := ctx .InsertCount + ctx .SelectCount + ctx .UpdateCount
27
+ if entire_percentage != 100 {
28
+ return fmt .Errorf (
29
+ "The number of operations as a percentage should be equal to 100, " +
30
+ "note that by default the percentage of inserts is 100" )
31
+ }
32
+ return nil
33
+ }
34
+
25
35
// spacePreset prepares space for a benchmark.
26
36
func spacePreset (ctx context.BenchCtx , tarantoolConnection * tarantool.Connection ) error {
27
37
dropBenchmarkSpace (tarantoolConnection )
28
38
return createBenchmarkSpace (tarantoolConnection )
29
39
}
30
40
31
41
// incrementRequest increases the counter of successful/failed requests depending on the presence of an error.
32
- func incrementRequest ( err error , results * Results ) {
42
+ func ( results * Results ) incrementRequestsCounters ( err error ) {
33
43
if err == nil {
34
44
results .successResultCount ++
35
45
} else {
@@ -39,29 +49,30 @@ func incrementRequest(err error, results *Results) {
39
49
}
40
50
41
51
// requestsLoop continuously executes the insert query until the benchmark time runs out.
42
- func requestsLoop (ctx context. BenchCtx , tarantoolConnection * tarantool. Connection , results * Results , backgroundCtx bctx.Context ) {
52
+ func requestsLoop (requestsSequence * RequestsSequence , backgroundCtx bctx.Context ) {
43
53
for {
44
54
select {
45
55
case <- backgroundCtx .Done ():
46
56
return
47
57
default :
48
- _ , err := tarantoolConnection .Exec (
49
- tarantool .Insert (
50
- benchSpaceName ,
51
- []interface {}{common .RandomString (ctx .KeySize ), common .RandomString (ctx .DataSize )}))
52
- incrementRequest (err , results )
58
+ requestsSequence .getNext ().execute ()
53
59
}
54
60
}
55
61
}
56
62
57
- // connectionLoop runs "ctx.SimultaneousRequests" requests execution threads through the same connection.
58
- func connectionLoop (ctx context.BenchCtx , tarantoolConnection * tarantool.Connection , results * Results , backgroundCtx bctx.Context ) {
63
+ // connectionLoop runs "ctx.SimultaneousRequests" requests execution threads
64
+ // through the same connection.
65
+ func connectionLoop (
66
+ ctx * context.BenchCtx ,
67
+ requestsSequence RequestsSequence ,
68
+ backgroundCtx bctx.Context ,
69
+ ) {
59
70
var connectionWait sync.WaitGroup
60
71
for i := 0 ; i < ctx .SimultaneousRequests ; i ++ {
61
72
connectionWait .Add (1 )
62
73
go func () {
63
74
defer connectionWait .Done ()
64
- requestsLoop (ctx , tarantoolConnection , results , backgroundCtx )
75
+ requestsLoop (& requestsSequence , backgroundCtx )
65
76
}()
66
77
}
67
78
@@ -72,6 +83,10 @@ func connectionLoop(ctx context.BenchCtx, tarantoolConnection *tarantool.Connect
72
83
func Run (ctx context.BenchCtx ) error {
73
84
rand .Seed (time .Now ().UnixNano ())
74
85
86
+ if err := verifyOperationsPercentage (& ctx ); err != nil {
87
+ return err
88
+ }
89
+
75
90
// Connect to tarantool and preset space for benchmark.
76
91
tarantoolConnection , err := tarantool .Connect (ctx .URL , tarantool.Opts {
77
92
User : ctx .User ,
@@ -90,7 +105,8 @@ func Run(ctx context.BenchCtx) error {
90
105
return err
91
106
}
92
107
93
- /// Сreate a "connectionPool" before starting the benchmark to exclude the connection establishment time from measurements.
108
+ // Сreate a "connectionPool" before starting the benchmark
109
+ // to exclude the connection establishment time from measurements.
94
110
connectionPool := make ([]* tarantool.Connection , ctx .Connections )
95
111
for i := 0 ; i < ctx .Connections ; i ++ {
96
112
connectionPool [i ], err = tarantool .Connect (ctx .URL , tarantool.Opts {
@@ -103,13 +119,28 @@ func Run(ctx context.BenchCtx) error {
103
119
defer connectionPool [i ].Close ()
104
120
}
105
121
106
- fmt .Println ("Benchmark start" )
122
+ // Pre-fill benchmark space if required.
123
+ if ctx .InsertCount == 0 || ctx .PreFillingCount != PreFillingCount {
124
+ fmt .Println ("The pre-filling of the space has started,\n " +
125
+ "because the insert operation is not specified\n " +
126
+ "or there was an explicit instruction for pre-filling." )
127
+ fmt .Println ("..." )
128
+ fillBenchmarkSpace (ctx , connectionPool )
129
+ fmt .Printf ("Pre-filling is finished.\n \n " )
130
+ }
131
+
132
+ fmt .Println ("Benchmark start." )
107
133
fmt .Println ("..." )
108
134
109
135
// The "context" will be used to stop all "connectionLoop" when the time is out.
110
136
backgroundCtx , cancel := bctx .WithCancel (bctx .Background ())
111
137
var waitGroup sync.WaitGroup
112
138
results := Results {}
139
+ getRandomTupleCommand := fmt .Sprintf (
140
+ "box.space.%s.index.%s:random" ,
141
+ benchSpaceName ,
142
+ benchSpacePrimaryIndexName ,
143
+ )
113
144
114
145
startTime := time .Now ()
115
146
timer := time .NewTimer (time .Duration (ctx .Duration * int (time .Second )))
@@ -119,7 +150,39 @@ func Run(ctx context.BenchCtx) error {
119
150
waitGroup .Add (1 )
120
151
go func (connection * tarantool.Connection ) {
121
152
defer waitGroup .Done ()
122
- connectionLoop (ctx , connection , & results , backgroundCtx )
153
+ requestsSequence := RequestsSequence {
154
+ []RequestsGenerator {
155
+ {
156
+ InsertRequest {
157
+ ctx ,
158
+ connection ,
159
+ & results ,
160
+ },
161
+ ctx .InsertCount ,
162
+ },
163
+ {
164
+ SelectRequest {
165
+ ctx ,
166
+ connection ,
167
+ & results ,
168
+ getRandomTupleCommand ,
169
+ },
170
+ ctx .SelectCount ,
171
+ },
172
+ {
173
+ UpdateRequest {
174
+ ctx ,
175
+ connection ,
176
+ & results ,
177
+ getRandomTupleCommand ,
178
+ },
179
+ ctx .UpdateCount ,
180
+ },
181
+ },
182
+ 0 ,
183
+ ctx .InsertCount ,
184
+ }
185
+ connectionLoop (& ctx , requestsSequence , backgroundCtx )
123
186
}(connectionPool [i ])
124
187
}
125
188
// Sends "signal" to all "connectionLoop" and waits for them to complete.
@@ -130,8 +193,10 @@ func Run(ctx context.BenchCtx) error {
130
193
results .duration = time .Since (startTime ).Seconds ()
131
194
results .requestsPerSecond = int (float64 (results .handledRequestsCount ) / results .duration )
132
195
133
- dropBenchmarkSpace (tarantoolConnection )
134
- fmt .Println ("Benchmark stop" )
196
+ if err := dropBenchmarkSpace (tarantoolConnection ); err != nil {
197
+ return err
198
+ }
199
+ fmt .Println ("Benchmark stop." )
135
200
136
201
printResults (results )
137
202
return nil
0 commit comments