Skip to content

Commit ea53ac8

Browse files
2 parents e363750 + dd6a6af commit ea53ac8

File tree

11 files changed

+69
-46
lines changed

11 files changed

+69
-46
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
same "printed page" as the copyright notice for easier
187187
identification within third-party archives.
188188

189-
Copyright [yyyy] [name of copyright owner]
189+
Copyright 2024 Momento Inc.
190190

191191
Licensed under the Apache License, Version 2.0 (the "License");
192192
you may not use this file except in compliance with the License.

src/Momento.Sdk/ITopicClient.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ public interface ITopicClient : IDisposable
4343
/// </summary>
4444
/// <param name="cacheName">Name of the cache containing the topic.</param>
4545
/// <param name="topicName">Name of the topic.</param>
46-
/// <param name="resumeAtSequenceNumber">The sequence number of the last message.
46+
/// <param name="resumeAtSequenceNumber">The sequence number of the last message.</param>
47+
/// <param name="resumeAtSequencePage">The sequence page of the last message.</param>
4748
/// If provided, the client will attempt to start the stream from that sequence number.</param>
4849
/// <returns>
4950
/// Task object representing the result of the subscribe operation. The
@@ -62,5 +63,5 @@ public interface ITopicClient : IDisposable
6263
/// }
6364
/// </code>
6465
/// </returns>
65-
public Task<TopicSubscribeResponse> SubscribeAsync(string cacheName, string topicName, ulong? resumeAtSequenceNumber = null);
66+
public Task<TopicSubscribeResponse> SubscribeAsync(string cacheName, string topicName, ulong? resumeAtSequenceNumber = null, ulong? resumeAtSequencePage = null);
6667
}

src/Momento.Sdk/Internal/LoggingUtils.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,11 +457,12 @@ public static void LogTraceTopicMessageReceived(this ILogger logger, string mess
457457
/// <param name="topicName"></param>
458458
/// <param name="lastSequenceNumber"></param>
459459
/// <param name="newSequenceNumber"></param>
460-
public static void LogTraceTopicDiscontinuityReceived(this ILogger logger, string cacheName, string topicName, ulong lastSequenceNumber, ulong newSequenceNumber)
460+
/// <param name="newSequencePage"></param>
461+
public static void LogTraceTopicDiscontinuityReceived(this ILogger logger, string cacheName, string topicName, ulong lastSequenceNumber, ulong newSequenceNumber, ulong newSequencePage)
461462
{
462463
if (logger.IsEnabled(LogLevel.Trace))
463464
{
464-
logger.LogTrace("Received discontinuity: cacheName: {}; topicName: {}, lastSequenceNumber: {}, newSequenceNumber: {}", cacheName, topicName, lastSequenceNumber, newSequenceNumber);
465+
logger.LogTrace("Received discontinuity: cacheName: {}; topicName: {}, lastSequenceNumber: {}, newSequenceNumber: {}, newSequencePage: {}", cacheName, topicName, lastSequenceNumber, newSequenceNumber, newSequencePage);
465466
}
466467
}
467468

src/Momento.Sdk/Internal/ScsDataClient.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Grpc.Core;
1010
using Microsoft.Extensions.Logging;
1111
using Momento.Protos.CacheClient;
12+
using Momento.Protos.Common;
1213
using Momento.Sdk.Config;
1314
using Momento.Sdk.Exceptions;
1415
using Momento.Sdk.Internal.ExtensionMethods;

src/Momento.Sdk/Internal/ScsTopicClient.cs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ public async Task<TopicPublishResponse> Publish(string cacheName, string topicNa
8383
}
8484

8585
public async Task<TopicSubscribeResponse> Subscribe(string cacheName, string topicName,
86-
ulong? resumeAtTopicSequenceNumber = null)
86+
ulong? resumeAtTopicSequenceNumber = null, ulong? resumeAtTopicSequencePage = null)
8787
{
88-
return await SendSubscribe(cacheName, topicName, resumeAtTopicSequenceNumber);
88+
return await SendSubscribe(cacheName, topicName, resumeAtTopicSequenceNumber, resumeAtTopicSequencePage);
8989
}
9090

9191
private const string RequestTypeTopicPublish = "TOPIC_PUBLISH";
@@ -116,23 +116,14 @@ private async Task<TopicPublishResponse> SendPublish(string cacheName, string to
116116
}
117117

118118
private async Task<TopicSubscribeResponse> SendSubscribe(string cacheName, string topicName,
119-
ulong? resumeAtTopicSequenceNumber)
119+
ulong? resumeAtTopicSequenceNumber, ulong? resumeAtTopicSequencePage)
120120
{
121-
var request = new _SubscriptionRequest
122-
{
123-
CacheName = cacheName,
124-
Topic = topicName
125-
};
126-
if (resumeAtTopicSequenceNumber != null)
127-
{
128-
request.ResumeAtTopicSequenceNumber = resumeAtTopicSequenceNumber.Value;
129-
}
130-
131121
SubscriptionWrapper subscriptionWrapper;
132122
try
133123
{
134124
_logger.LogTraceExecutingTopicRequest(RequestTypeTopicSubscribe, cacheName, topicName);
135-
subscriptionWrapper = new SubscriptionWrapper(grpcManager, cacheName, topicName, _exceptionMapper, _logger);
125+
subscriptionWrapper = new SubscriptionWrapper(grpcManager, cacheName, topicName,
126+
resumeAtTopicSequenceNumber, resumeAtTopicSequencePage, _exceptionMapper, _logger);
136127
await subscriptionWrapper.Subscribe();
137128
}
138129
catch (Exception e)
@@ -157,15 +148,19 @@ private class SubscriptionWrapper : IDisposable
157148
private readonly ILogger _logger;
158149

159150
private AsyncServerStreamingCall<_SubscriptionItem>? _subscription;
160-
private ulong? _lastSequenceNumber;
151+
private ulong _lastSequenceNumber;
152+
private ulong _lastSequencePage;
161153
private bool _subscribed;
162154

163155
public SubscriptionWrapper(TopicGrpcManager grpcManager, string cacheName,
164-
string topicName, CacheExceptionMapper exceptionMapper, ILogger logger)
156+
string topicName, ulong? resumeAtTopicSequenceNumber, ulong? resumeAtTopicSequencePage,
157+
CacheExceptionMapper exceptionMapper, ILogger logger)
165158
{
166159
_grpcManager = grpcManager;
167160
_cacheName = cacheName;
168161
_topicName = topicName;
162+
_lastSequenceNumber = resumeAtTopicSequenceNumber ?? 0;
163+
_lastSequencePage = resumeAtTopicSequencePage ?? 0;
169164
_exceptionMapper = exceptionMapper;
170165
_logger = logger;
171166
}
@@ -177,10 +172,9 @@ public async Task Subscribe()
177172
CacheName = _cacheName,
178173
Topic = _topicName
179174
};
180-
if (_lastSequenceNumber != null)
181-
{
182-
request.ResumeAtTopicSequenceNumber = _lastSequenceNumber.Value;
183-
}
175+
176+
request.ResumeAtTopicSequenceNumber = _lastSequenceNumber;
177+
request.SequencePage = _lastSequencePage;
184178

185179
_logger.LogTraceExecutingTopicRequest(RequestTypeTopicSubscribe, _cacheName, _topicName);
186180
var subscription = _grpcManager.Client.subscribe(request, new CallOptions());
@@ -247,14 +241,16 @@ public async Task Subscribe()
247241
{
248242
case _SubscriptionItem.KindOneofCase.Item:
249243
_lastSequenceNumber = message.Item.TopicSequenceNumber;
244+
_lastSequencePage = message.Item.SequencePage;
245+
250246
switch (message.Item.Value.KindCase)
251247
{
252248
case _TopicValue.KindOneofCase.Text:
253249
_logger.LogTraceTopicMessageReceived("text", _cacheName, _topicName);
254-
return new TopicMessage.Text(message.Item.Value, checked((long)_lastSequenceNumber), message.Item.PublisherId == "" ? null : message.Item.PublisherId);
250+
return new TopicMessage.Text(message.Item.Value, _lastSequenceNumber, _lastSequencePage, message.Item.PublisherId == "" ? null : message.Item.PublisherId);
255251
case _TopicValue.KindOneofCase.Binary:
256252
_logger.LogTraceTopicMessageReceived("binary", _cacheName, _topicName);
257-
return new TopicMessage.Binary(message.Item.Value, checked((long)_lastSequenceNumber), message.Item.PublisherId == "" ? null : message.Item.PublisherId);
253+
return new TopicMessage.Binary(message.Item.Value, _lastSequenceNumber, _lastSequencePage, message.Item.PublisherId == "" ? null : message.Item.PublisherId);
258254
case _TopicValue.KindOneofCase.None:
259255
default:
260256
_logger.LogTraceTopicMessageReceived("unknown", _cacheName, _topicName);
@@ -264,10 +260,12 @@ public async Task Subscribe()
264260
break;
265261
case _SubscriptionItem.KindOneofCase.Discontinuity:
266262
_logger.LogTraceTopicDiscontinuityReceived(_cacheName, _topicName,
267-
message.Discontinuity.LastTopicSequence, message.Discontinuity.NewTopicSequence);
263+
message.Discontinuity.LastTopicSequence, message.Discontinuity.NewTopicSequence, message.Discontinuity.NewSequencePage);
268264
_lastSequenceNumber = message.Discontinuity.NewTopicSequence;
269-
return new TopicSystemEvent.Discontinuity(checked((long)message.Discontinuity.LastTopicSequence),
270-
checked((long)message.Discontinuity.NewTopicSequence));
265+
_lastSequencePage = message.Discontinuity.NewSequencePage;
266+
return new TopicSystemEvent.Discontinuity(message.Discontinuity.LastTopicSequence,
267+
message.Discontinuity.NewTopicSequence,
268+
message.Discontinuity.NewSequencePage);
271269
case _SubscriptionItem.KindOneofCase.Heartbeat:
272270
_logger.LogTraceTopicMessageReceived("heartbeat", _cacheName, _topicName);
273271
return new TopicSystemEvent.Heartbeat();

src/Momento.Sdk/Internal/TopicGrpcManager.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#endif
1313
using Microsoft.Extensions.Logging;
1414
using Momento.Protos.CacheClient.Pubsub;
15+
using Momento.Protos.Common;
1516
using Momento.Sdk.Config;
1617
using Momento.Sdk.Config.Middleware;
1718
using Momento.Sdk.Config.Retry;
@@ -69,7 +70,7 @@ public class TopicGrpcManager : GrpcManager
6970
{
7071
public readonly IPubsubClient Client;
7172

72-
internal TopicGrpcManager(ITopicConfiguration config, string authToken, string endpoint): base(config.TransportStrategy.GrpcConfig, config.LoggerFactory, authToken, endpoint, "TopicGrpcManager")
73+
internal TopicGrpcManager(ITopicConfiguration config, string authToken, string endpoint) : base(config.TransportStrategy.GrpcConfig, config.LoggerFactory, authToken, endpoint, "TopicGrpcManager")
7374
{
7475
var middlewares = new List<IMiddleware>
7576
{

src/Momento.Sdk/Momento.Sdk.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
<ItemGroup>
7070
<PackageReference Include="Grpc.Net.Client" Version="2.63.0" />
7171
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="7.0.0" />
72-
<PackageReference Include="Momento.Protos" Version="0.106.0" />
72+
<PackageReference Include="Momento.Protos" Version="0.119.2" />
7373
<PackageReference Include="JWT" Version="9.0.3" />
7474
<PackageReference Include="System.Threading.Channels" Version="6.0.0" />
7575
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />

src/Momento.Sdk/Responses/Topic/TopicMessage.cs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,11 @@ public class Text : TopicMessage
4242
/// <summary>
4343
/// A topic message containing a text value.
4444
/// </summary>
45-
public Text(_TopicValue topicValue, long topicSequenceNumber, string? tokenId = null)
45+
public Text(_TopicValue topicValue, ulong topicSequenceNumber, ulong topicSequencePage, string? tokenId = null)
4646
{
4747
Value = topicValue.Text;
4848
TopicSequenceNumber = topicSequenceNumber;
49+
TopicSequencePage = topicSequencePage;
4950
TokenId = tokenId;
5051
}
5152

@@ -57,7 +58,12 @@ public Text(_TopicValue topicValue, long topicSequenceNumber, string? tokenId =
5758
/// <summary>
5859
/// The sequence number of this message.
5960
/// </summary>
60-
public long TopicSequenceNumber { get; }
61+
public ulong TopicSequenceNumber { get; }
62+
63+
/// <summary>
64+
/// The sequence page of this message.
65+
/// </summary>
66+
public ulong TopicSequencePage { get; }
6167

6268
/// <summary>
6369
/// The TokenId that was used to publish the message, or null if the token did not have an id.
@@ -68,7 +74,7 @@ public Text(_TopicValue topicValue, long topicSequenceNumber, string? tokenId =
6874
/// <inheritdoc />
6975
public override string ToString()
7076
{
71-
return $"{base.ToString()}: Value: \"{this.Value.Truncate()}\" SequenceNumber: {this.TopicSequenceNumber} TokenId: \"{this.TokenId}\"";
77+
return $"{base.ToString()}: Value: \"{this.Value.Truncate()}\" SequenceNumber: {this.TopicSequenceNumber} SequencePage: {this.TopicSequencePage} TokenId: \"{this.TokenId}\"";
7278
}
7379
}
7480

@@ -80,13 +86,15 @@ public class Binary : TopicMessage
8086
/// <summary>
8187
/// A topic message containing a binary value.
8288
/// </summary>
83-
public Binary(_TopicValue topicValue, long topicSequenceNumber, string? tokenId = null)
89+
public Binary(_TopicValue topicValue, ulong topicSequenceNumber, ulong topicSequencePage, string? tokenId = null)
8490
{
8591
Value = topicValue.Binary.ToByteArray();
8692
TopicSequenceNumber = topicSequenceNumber;
93+
TopicSequencePage = topicSequencePage;
8794
TokenId = tokenId;
8895
}
8996

97+
9098
/// <summary>
9199
/// The binary value of this message.
92100
/// </summary>
@@ -95,7 +103,12 @@ public Binary(_TopicValue topicValue, long topicSequenceNumber, string? tokenId
95103
/// <summary>
96104
/// The sequence number of this message.
97105
/// </summary>
98-
public long TopicSequenceNumber { get; }
106+
public ulong TopicSequenceNumber { get; }
107+
108+
/// <summary>
109+
/// The sequence page of this message.
110+
/// </summary>
111+
public ulong TopicSequencePage { get; }
99112

100113
/// <summary>
101114
/// The TokenId that was used to publish the message, or null if the token did not have an id.
@@ -106,7 +119,7 @@ public Binary(_TopicValue topicValue, long topicSequenceNumber, string? tokenId
106119
/// <inheritdoc />
107120
public override string ToString()
108121
{
109-
return $"{base.ToString()}: Value: \"{Value.ToPrettyHexString().Truncate()}\" SequenceNumber: {this.TopicSequenceNumber} TokenId: \"{this.TokenId}\"";
122+
return $"{base.ToString()}: Value: \"{Value.ToPrettyHexString().Truncate()}\" SequenceNumber: {this.TopicSequenceNumber} SequencePage: {this.TopicSequencePage} TokenId: \"{this.TokenId}\"";
110123
}
111124
}
112125

src/Momento.Sdk/Responses/Topic/TopicSystemEvent.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,33 @@ public class Discontinuity : TopicSystemEvent
3232
/// </summary>
3333
/// <param name="lastKnownSequenceNumber">The last known sequence number before the discontinuity.</param>
3434
/// <param name="sequenceNumber">The sequence number of the discontinuity.</param>
35-
public Discontinuity(long lastKnownSequenceNumber, long sequenceNumber)
35+
/// <param name="sequencePage">The sequence page of the discontinuity.</param>
36+
public Discontinuity(ulong lastKnownSequenceNumber, ulong sequenceNumber, ulong sequencePage)
3637
{
3738
LastKnownSequenceNumber = lastKnownSequenceNumber;
3839
SequenceNumber = sequenceNumber;
40+
SequencePage = sequencePage;
3941
}
4042

4143
/// <summary>
4244
/// The last known sequence number before the discontinuity.
4345
/// </summary>
44-
public long LastKnownSequenceNumber { get; }
46+
public ulong LastKnownSequenceNumber { get; }
47+
4548
/// <summary>
4649
/// The sequence number of the discontinuity.
4750
/// </summary>
48-
public long SequenceNumber { get; }
51+
public ulong SequenceNumber { get; }
52+
53+
/// <summary>
54+
/// The sequence page of the discontinuity.
55+
/// </summary>
56+
public ulong SequencePage { get; }
4957

5058
/// <inheritdoc/>
5159
public override string ToString()
5260
{
53-
return $"{base.ToString()}: LastKnownSequenceNumber: {LastKnownSequenceNumber} SequenceNumber: {SequenceNumber}";
61+
return $"{base.ToString()}: LastKnownSequenceNumber: {LastKnownSequenceNumber} SequenceNumber: {SequenceNumber} SequencePage: {SequencePage}";
5462
}
5563
}
5664
}

src/Momento.Sdk/TopicClient.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public async Task<TopicPublishResponse> PublishAsync(string cacheName, string to
5959
}
6060

6161
/// <inheritdoc />
62-
public async Task<TopicSubscribeResponse> SubscribeAsync(string cacheName, string topicName, ulong? resumeAtSequenceNumber = null)
62+
public async Task<TopicSubscribeResponse> SubscribeAsync(string cacheName, string topicName, ulong? resumeAtSequenceNumber = null, ulong? resumeAtSequencePage = null)
6363
{
6464
try
6565
{
@@ -70,7 +70,7 @@ public async Task<TopicSubscribeResponse> SubscribeAsync(string cacheName, strin
7070
{
7171
return new TopicSubscribeResponse.Error(new InvalidArgumentException(e.Message));
7272
}
73-
return await scsTopicClient.Subscribe(cacheName, topicName, resumeAtSequenceNumber);
73+
return await scsTopicClient.Subscribe(cacheName, topicName, resumeAtSequenceNumber, resumeAtSequencePage);
7474
}
7575

7676
/// <inheritdoc />

0 commit comments

Comments
 (0)