Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: return topic subscribe error immediately if subscription limit reached #62

Merged
merged 9 commits into from
Jan 9, 2024

Conversation

anitarua
Copy link
Collaborator

@anitarua anitarua commented Jan 5, 2024

addresses #55

Checks that the first message is a heartbeat before returning a TopicSubscription or TopicSubscribeError response. Now, if a user tries to subscribe >100 times, they will get a TopicSubscribeError saying they've reached the 100 subscriber limit.

Also did some testing and determined that the keepalive settings seemed to be interfering with the ability to reconnect. Keepalive settings were not playing well with the default backoff and retry strategy that dart-grpc uses, so removed them for now after confirming retries still work.

Before (with keepalive settings):

FINE: 2024-01-04 15:20:46.537611: topic client received a heartbeat
FINE: 2024-01-04 15:20:53.061621: Attempting to reconnect after receiving error: gRPC Error (code: 2, codeName: UNKNOWN, message: HTTP/2 error: Connection error: Connection is being forcefully terminated. (errorCode: 10), details: null, rawResponse: null, trailers: {})
FINE: 2024-01-04 15:20:53.065014: Error reconnecting: Error connecting: Connection shutting down

After (without keepalive settings):

FINE: 2024-01-05 10:00:06.773596: topic client received a heartbeat
FINE: 2024-01-05 10:06:10.777344: Attempting to reconnect after receiving error: gRPC Error (code: 2, codeName: UNKNOWN, message: HTTP/2 error: Connection error: Connection is being forcefully terminated. (errorCode: 10), details: null, rawResponse: null, trailers: {})

Comment on lines +64 to +81
Future<TopicSubscribeResponse> subscribe(String cacheName, String topicName,
{Int64? resumeAtTopicSequenceNumber}) async {
var request = SubscriptionRequest_();
request.cacheName = cacheName;
request.topic = topicName;
request.resumeAtTopicSequenceNumber =
resumeAtTopicSequenceNumber ?? Int64(0);
try {
var stream = _grpcManager.client.subscribe(request);
return TopicSubscription(stream, request.resumeAtTopicSequenceNumber,
this, cacheName, topicName);
final subscription = TopicSubscription(stream,
request.resumeAtTopicSequenceNumber, this, cacheName, topicName);

try {
await subscription.init();
return subscription;
} catch (e) {
rethrow;
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

had to make subscribe an async function in order to run the init method that checks for the first message being a heartbeat

keepAlive: ClientKeepAliveOptions(
pingInterval: Duration(seconds: 10),
timeout: Duration(seconds: 5))));
_channel = ClientChannel(credentialProvider.cacheEndpoint);
Copy link
Collaborator Author

@anitarua anitarua Jan 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the keepalive settings as it seemed to interfere with the default retry strategy dart-grpc already implements (seems to completely close the grpc channel without any possibility of reconnecting using the generated pubsub client)


TopicSubscription(this._stream, this.lastSequenceNumber, this._client,
this.cacheName, this.topicName);
this.cacheName, this.topicName) {
_broadcastStream = _stream.asBroadcastStream();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

creating a broadcast stream allows for multiple subscribers to consume messages from the stream.
In this case, there's one consumer in the init method to check if the first message is a heartbeat and the other consumer is the end user

@@ -14,7 +14,7 @@ dependencies:
logging: ^1.2.0
protobuf: ^3.1.0
string_validator: ^1.0.2
uuid: ^4.3.1
uuid: ^4.2.2
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flutter demo app couldn't import the momento package because flutter uses uuid < 4.3.0

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmmm, makes me question how dart handles transient deps, and if our other deps could cause a similar issue with other programs. I think is OK for now, but something to keep an eye out on

@anitarua anitarua marked this pull request as ready for review January 5, 2024 19:42
Copy link
Collaborator

@bruuuuuuuce bruuuuuuuce left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:


```bash
flutter devices
flutter run -d <device_id> --dart-define="MOMENTO_API_KEY=<your-api-key>"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦾

@@ -14,7 +14,7 @@ dependencies:
logging: ^1.2.0
protobuf: ^3.1.0
string_validator: ^1.0.2
uuid: ^4.3.1
uuid: ^4.2.2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmmm, makes me question how dart handles transient deps, and if our other deps could cause a similar issue with other programs. I think is OK for now, but something to keep an eye out on

@anitarua anitarua merged commit 30b9f49 into main Jan 9, 2024
2 checks passed
@anitarua anitarua deleted the fix-subscriptions branch January 9, 2024 17:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants