Skip to content

Commit ec37afd

Browse files
dev: update tank options (#486)
1 parent da2a3a6 commit ec37afd

File tree

2 files changed

+65
-37
lines changed

2 files changed

+65
-37
lines changed

src/Ydb.Sdk/test/Ydb.Sdk.Ado.Stress.Loader/Cli.cs

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,17 @@ public static class Cli
3131
private static readonly Option<int> TotalTestTimeSeconds = new("--total-time", () => 14400,
3232
"Total test duration in seconds");
3333

34-
private static readonly Option<string?> SaFilePath = new("--sa-file-path",
35-
"Path to Service Account file for authentication");
34+
private static readonly Option<string?> SaFilePath =
35+
new("--sa-file-path", "Path to Service Account file for authentication");
3636

37-
private static readonly Option<string> TestQuery = new("--test-query",
38-
() => "SELECT 1 as test_column",
39-
"SQL query to execute during stress test"
40-
);
37+
private static readonly Option<string> TestQuery =
38+
new("--test-query", () => "SELECT 1 as test_column", "SQL query to execute during stress test");
39+
40+
private static readonly Option<int> ThrottlingInterval =
41+
new("--throttling-interval", () => 100, "Throttling interval in seconds");
42+
43+
private static readonly Option<int> WorkerCount =
44+
new("--worker-count", () => 100, "Worker count");
4145

4246
private static readonly Command StressLoadCommand = new(
4347
"cycle",
@@ -53,7 +57,9 @@ public static class Cli
5357
MinDurationSeconds,
5458
TotalTestTimeSeconds,
5559
SaFilePath,
56-
TestQuery
60+
TestQuery,
61+
ThrottlingInterval,
62+
WorkerCount
5763
};
5864

5965
private static readonly Command LoadCommand = new(
@@ -63,7 +69,8 @@ public static class Cli
6369
TotalTestTimeSeconds,
6470
ConnectionString,
6571
SaFilePath,
66-
TestQuery
72+
TestQuery,
73+
WorkerCount
6774
};
6875

6976
public static readonly RootCommand RootCommand = new("YDB ADO.NET Stress Test Tank - Variable Load Generator")
@@ -89,7 +96,9 @@ static Cli()
8996
MinDurationSeconds,
9097
TotalTestTimeSeconds,
9198
SaFilePath,
92-
TestQuery
99+
TestQuery,
100+
ThrottlingInterval,
101+
WorkerCount
93102
)
94103
);
95104

@@ -102,7 +111,8 @@ static Cli()
102111
ConnectionString,
103112
TotalTestTimeSeconds,
104113
SaFilePath,
105-
TestQuery
114+
TestQuery,
115+
WorkerCount
106116
)
107117
);
108118
}
@@ -118,7 +128,9 @@ public class StressConfigBinder(
118128
Option<int> minDurationSeconds,
119129
Option<int> totalTestTimeSeconds,
120130
Option<string?> saFilePath,
121-
Option<string> testQuery
131+
Option<string> testQuery,
132+
Option<int> throttlingInterval,
133+
Option<int> workerCount
122134
) : BinderBase<StressConfig>
123135
{
124136
protected override StressConfig GetBoundValue(BindingContext bindingContext) => new(
@@ -131,22 +143,26 @@ Option<string> testQuery
131143
MinDurationSeconds: bindingContext.ParseResult.GetValueForOption(minDurationSeconds),
132144
TotalTestTimeSeconds: bindingContext.ParseResult.GetValueForOption(totalTestTimeSeconds),
133145
SaFilePath: bindingContext.ParseResult.GetValueForOption(saFilePath),
134-
TestQuery: bindingContext.ParseResult.GetValueForOption(testQuery)!
146+
TestQuery: bindingContext.ParseResult.GetValueForOption(testQuery)!,
147+
ThrottlingInterval: bindingContext.ParseResult.GetValueForOption(throttlingInterval),
148+
WorkerCount: bindingContext.ParseResult.GetValueForOption(workerCount)
135149
);
136150
}
137151

138152
public class LoadConfigBinder(
139153
Argument<string> connectionString,
140154
Option<int> totalTestTimeSeconds,
141155
Option<string?> saFilePath,
142-
Option<string> testQuery
156+
Option<string> testQuery,
157+
Option<int> workerCount
143158
) : BinderBase<LoadConfig>
144159
{
145160
protected override LoadConfig GetBoundValue(BindingContext bindingContext) => new(
146161
bindingContext.ParseResult.GetValueForArgument(connectionString),
147162
bindingContext.ParseResult.GetValueForOption(totalTestTimeSeconds),
148163
bindingContext.ParseResult.GetValueForOption(saFilePath),
149-
bindingContext.ParseResult.GetValueForOption(testQuery)!
164+
bindingContext.ParseResult.GetValueForOption(testQuery)!,
165+
bindingContext.ParseResult.GetValueForOption(workerCount)
150166
);
151167
}
152168

@@ -160,12 +176,15 @@ public record StressConfig(
160176
int MinDurationSeconds,
161177
int TotalTestTimeSeconds,
162178
string? SaFilePath,
163-
string TestQuery
179+
string TestQuery,
180+
int ThrottlingInterval,
181+
int WorkerCount
164182
);
165183

166184
public record LoadConfig(
167185
string ConnectionString,
168186
int TotalTestTimeSeconds,
169187
string? SaFilePath,
170-
string TestQuery
188+
string TestQuery,
189+
int WorkerCount
171190
);

src/Ydb.Sdk/test/Ydb.Sdk.Ado.Stress.Loader/StressLoadTank.cs

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -110,35 +110,44 @@ private async Task StartWorkersForRpsAsync(int targetRps, CancellationToken canc
110110

111111
_logger.LogInformation("Starting shooting for {TargetRps} RPS", targetRps);
112112

113-
while (!cancellationToken.IsCancellationRequested)
113+
var workers = new List<Task>();
114+
for (var i = 0; i < _config.WorkerCount; i++)
114115
{
115-
using var lease = await rateLimiter.AcquireAsync(1, cancellationToken);
116-
117-
if (!lease.IsAcquired)
118-
{
119-
continue;
120-
}
121-
122-
_ = Task.Run(async () =>
116+
workers.Add(Task.Run(async () =>
123117
{
124-
try
118+
while (!cancellationToken.IsCancellationRequested)
125119
{
126-
await using var ydbConnection = new YdbConnection(_settings);
127-
await ydbConnection.OpenAsync(cancellationToken);
128-
await new YdbCommand(ydbConnection) { CommandText = _config.TestQuery }
129-
.ExecuteNonQueryAsync(cancellationToken);
130-
}
131-
catch (YdbException e)
132-
{
133-
if (e.Code == StatusCode.ClientTransportTimeout)
120+
// ReSharper disable once AccessToDisposedClosure
121+
using var lease = await rateLimiter.AcquireAsync(1, cancellationToken);
122+
await Task.Delay(Random.Shared.Next(_config.ThrottlingInterval), cancellationToken);
123+
124+
if (!lease.IsAcquired)
134125
{
135-
return;
126+
await Task.Delay(10, cancellationToken);
127+
continue;
136128
}
137129

138-
_logger.LogError(e, "Fail operation");
130+
try
131+
{
132+
await using var ydbConnection = new YdbConnection(_settings);
133+
await ydbConnection.OpenAsync(cancellationToken);
134+
await new YdbCommand(ydbConnection) { CommandText = _config.TestQuery }
135+
.ExecuteNonQueryAsync(cancellationToken);
136+
}
137+
catch (YdbException e)
138+
{
139+
if (e.Code == StatusCode.ClientTransportTimeout)
140+
{
141+
return;
142+
}
143+
144+
_logger.LogError(e, "Fail operation");
145+
}
139146
}
140-
}, cancellationToken);
147+
}, cancellationToken));
141148
}
149+
150+
await Task.WhenAll(workers);
142151
}
143152

144153
private void ValidateConfig()

0 commit comments

Comments
 (0)