Skip to content

Commit 59067b4

Browse files
authored
Merge pull request #2341 from Cratis:fix/grpc-message-size
Making gRPC message size configurable and defaulting to 100MB
2 parents 3b84983 + 363efc1 commit 59067b4

File tree

7 files changed

+106
-1
lines changed

7 files changed

+106
-1
lines changed

Documentation/clients/aspnetcore/index.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ You can configure Chronicle using your `appsettings.json` file. The configuratio
3636
"SoftwareCommit": "abc123",
3737
"ProgramIdentifier": "my-service",
3838
"AutoDiscoverAndRegister": true,
39-
"ConnectTimeout": 5
39+
"ConnectTimeout": 5,
40+
"MaxReceiveMessageSize": 104857600,
41+
"MaxSendMessageSize": 104857600
4042
}
4143
}
4244
```
@@ -68,6 +70,10 @@ Chronicle__ProgramIdentifier=my-service
6870
# Connection settings
6971
Chronicle__ConnectTimeout=10
7072
Chronicle__AutoDiscoverAndRegister=true
73+
74+
# gRPC message size limits (in bytes, defaults to 100 MB)
75+
Chronicle__MaxReceiveMessageSize=104857600
76+
Chronicle__MaxSendMessageSize=104857600
7177
```
7278

7379
Environment variables take precedence over `appsettings.json`, making them ideal for environment-specific configuration.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# gRPC Message Size Configuration
2+
3+
When working with large event batches or queries that return many events, you may encounter gRPC message size limits. Chronicle provides configuration options to adjust the maximum send and receive message sizes.
4+
5+
## Default Settings
6+
7+
By default, Chronicle sets both `MaxReceiveMessageSize` and `MaxSendMessageSize` to **100 MB** (104,857,600 bytes). This is significantly higher than the default gRPC limit of 4 MB, making it suitable for most scenarios involving large event collections.
8+
9+
## Configuring Message Sizes
10+
11+
You can configure the message sizes when creating a `ChronicleClient` or through options:
12+
13+
```csharp
14+
var options = new ChronicleOptions
15+
{
16+
Url = new ChronicleUrl("chronicle://localhost:35000"),
17+
MaxReceiveMessageSize = 200 * 1024 * 1024, // 200 MB
18+
MaxSendMessageSize = 200 * 1024 * 1024 // 200 MB
19+
};
20+
21+
var client = new ChronicleClient(options);
22+
```
23+
24+
## Configuration via appsettings.json
25+
26+
For ASP.NET Core applications, you can configure message sizes in your `appsettings.json`:
27+
28+
```json
29+
{
30+
"Chronicle": {
31+
"Url": "chronicle://localhost:35000",
32+
"MaxReceiveMessageSize": 209715200,
33+
"MaxSendMessageSize": 209715200
34+
}
35+
}
36+
```
37+
38+
## Configuration via Environment Variables
39+
40+
Message sizes can also be set using environment variables:
41+
42+
```bash
43+
Chronicle__MaxReceiveMessageSize=209715200
44+
Chronicle__MaxSendMessageSize=209715200
45+
```
46+
47+
## Understanding the Error
48+
49+
If you encounter an error like:
50+
51+
```
52+
Status(StatusCode="ResourceExhausted", Detail="Received message exceeds the maximum configured message size.")
53+
```
54+
55+
This indicates that the response from the server exceeds the `MaxReceiveMessageSize`. You should increase this value to accommodate larger responses.
56+
57+
## Recommendations
58+
59+
- **Default (100 MB)**: Suitable for most applications with moderate event batch sizes
60+
- **200+ MB**: Consider for applications that frequently query large event ranges or work with many events
61+
- **Performance Considerations**: Larger message sizes consume more memory. Balance your needs with available resources
62+
- **Server Configuration**: Ensure the Chronicle Kernel server is also configured to handle the message sizes you need
63+
64+
## Null Values
65+
66+
Setting either property to `null` will use the gRPC default (4 MB), which is generally **not recommended** for Chronicle applications:
67+
68+
```csharp
69+
var options = new ChronicleOptions
70+
{
71+
MaxReceiveMessageSize = null, // Uses gRPC default of 4 MB - not recommended
72+
MaxSendMessageSize = null // Uses gRPC default of 4 MB - not recommended
73+
};
74+
```

Documentation/recipes/configuration/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ This section contains recipes for configuring Chronicle in various scenarios and
55
## Topics
66

77
- [Camel Casing](camel-casing.md) - Configure camel case naming policy for JSON serialization
8+
- [gRPC Message Size](grpc-message-size.md) - Configure maximum message sizes for large event collections

Source/Clients/Connections/ChronicleConnection.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ public sealed class ChronicleConnection : IChronicleConnection, IChronicleServic
3535
{
3636
readonly ChronicleUrl _url;
3737
readonly int _connectTimeout;
38+
readonly int? _maxReceiveMessageSize;
39+
readonly int? _maxSendMessageSize;
3840
readonly ITaskFactory _tasks;
3941
readonly ICorrelationIdAccessor _correlationIdAccessor;
4042
readonly CancellationToken _cancellationToken;
@@ -51,6 +53,8 @@ public sealed class ChronicleConnection : IChronicleConnection, IChronicleServic
5153
/// </summary>
5254
/// <param name="url"><see cref="ChronicleUrl"/> to connect with.</param>
5355
/// <param name="connectTimeout">Timeout when connecting in seconds.</param>
56+
/// <param name="maxReceiveMessageSize">Maximum receive message size in bytes.</param>
57+
/// <param name="maxSendMessageSize">Maximum send message size in bytes.</param>
5458
/// <param name="connectionLifecycle"><see cref="IConnectionLifecycle"/> for when connection state changes.</param>
5559
/// <param name="tasks"><see cref="ITaskFactory"/> to create tasks with.</param>
5660
/// <param name="correlationIdAccessor"><see cref="ICorrelationIdAccessor"/> to access the correlation ID.</param>
@@ -60,6 +64,8 @@ public sealed class ChronicleConnection : IChronicleConnection, IChronicleServic
6064
public ChronicleConnection(
6165
ChronicleUrl url,
6266
int connectTimeout,
67+
int? maxReceiveMessageSize,
68+
int? maxSendMessageSize,
6369
IConnectionLifecycle connectionLifecycle,
6470
ITaskFactory tasks,
6571
ICorrelationIdAccessor correlationIdAccessor,
@@ -69,6 +75,8 @@ public ChronicleConnection(
6975
GrpcClientFactory.AllowUnencryptedHttp2 = true;
7076
_url = url;
7177
_connectTimeout = connectTimeout;
78+
_maxReceiveMessageSize = maxReceiveMessageSize;
79+
_maxSendMessageSize = maxSendMessageSize;
7280
Lifecycle = connectionLifecycle;
7381
_tasks = tasks;
7482
_correlationIdAccessor = correlationIdAccessor;
@@ -191,6 +199,8 @@ GrpcChannel CreateGrpcChannel()
191199
new GrpcChannelOptions
192200
{
193201
HttpHandler = httpHandler,
202+
MaxReceiveMessageSize = _maxReceiveMessageSize,
203+
MaxSendMessageSize = _maxSendMessageSize,
194204
ServiceConfig = new ServiceConfig
195205
{
196206
MethodConfigs =

Source/Clients/Connections/ServiceCollectionExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ public static IServiceCollection AddCratisChronicleConnection(this IServiceColle
4242
return new ChronicleConnection(
4343
url,
4444
5,
45+
null,
46+
null,
4547
connectionLifecycle,
4648
new Cratis.Tasks.TaskFactory(),
4749
correlationIdAccessor,

Source/Clients/DotNET/ChronicleClient.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ public ChronicleClient(ChronicleOptions options)
6666
_connection = new ChronicleConnection(
6767
options.Url,
6868
options.ConnectTimeout,
69+
options.MaxReceiveMessageSize,
70+
options.MaxSendMessageSize,
6971
connectionLifecycle,
7072
new Tasks.TaskFactory(),
7173
options.CorrelationIdAccessor,

Source/Clients/DotNET/ChronicleOptions.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,16 @@ public ChronicleOptions() : this(ChronicleUrl.Default)
117117
/// </summary>
118118
public int ConnectTimeout { get; set; } = connectTimeout;
119119

120+
/// <summary>
121+
/// Gets or sets the maximum receive message size in bytes for gRPC messages. Defaults to 100 MB.
122+
/// </summary>
123+
public int? MaxReceiveMessageSize { get; set; } = 100 * 1024 * 1024;
124+
125+
/// <summary>
126+
/// Gets or sets the maximum send message size in bytes for gRPC messages. Defaults to 100 MB.
127+
/// </summary>
128+
public int? MaxSendMessageSize { get; set; } = 100 * 1024 * 1024;
129+
120130
/// <summary>
121131
/// Gets the <see cref="ILoggerFactory"/> to use internally in the client.
122132
/// </summary>

0 commit comments

Comments
 (0)