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

[ECO-4873] Max message size fix #1947

Merged
merged 2 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Source/ARTConnection.m
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#import "ARTConnection+Private.h"

#import "ARTDefault.h"
#import "ARTRealtime+Private.h"
#import "ARTEventEmitter+Private.h"
#import "ARTQueuedDealloc.h"
#import "ARTRealtimeChannels+Private.h"
#import "ARTRealtimeChannel+Private.h"
#import "ARTDefault+Private.h"
#import "ARTClientOptions+Private.h"

#define IsInactiveConnectionState(state) (state == ARTRealtimeClosing || state == ARTRealtimeClosed || state == ARTRealtimeFailed || state == ARTRealtimeSuspended)

Expand Down Expand Up @@ -193,6 +195,12 @@ - (NSString *)key_nosync {
return _key;
}

- (NSInteger)maxMessageSize {
if (_maxMessageSize)
return _maxMessageSize;
return _realtime.options.isProductionEnvironment ? [ARTDefault maxProductionMessageSize] : [ARTDefault maxSandboxMessageSize];
}

- (ARTRealtimeConnectionState)state_nosync {
return _state;
}
Expand Down
32 changes: 30 additions & 2 deletions Source/ARTDefault.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
static NSString *const ARTDefault_realtimeHost = @"realtime.ably.io";

static NSTimeInterval _connectionStateTtl = 60.0;
static NSInteger _maxMessageSize = 65536;
static NSInteger _maxMessageSize = 0;
static NSInteger _maxProductionMessageSize = 65536;
static NSInteger _maxSandboxMessageSize = 16384;

@implementation ARTDefault

Expand Down Expand Up @@ -70,7 +72,21 @@ + (NSTimeInterval)realtimeRequestTimeout {
}

+ (NSInteger)maxMessageSize {
return _maxMessageSize;
if (_maxMessageSize)
return _maxMessageSize;
#if DEBUG
return _maxSandboxMessageSize;
#else
return _maxProductionMessageSize;
#endif
}

+ (NSInteger)maxSandboxMessageSize {
return _maxSandboxMessageSize;
}

+ (NSInteger)maxProductionMessageSize {
return _maxProductionMessageSize;
}

+ (void)setConnectionStateTtl:(NSTimeInterval)value {
Expand All @@ -85,6 +101,18 @@ + (void)setMaxMessageSize:(NSInteger)value {
}
}

+ (void)setMaxProductionMessageSize:(NSInteger)value {
@synchronized (self) {
_maxProductionMessageSize = value;
}
}

+ (void)setMaxSandboxMessageSize:(NSInteger)value {
@synchronized (self) {
_maxSandboxMessageSize = value;
}
}

+ (NSString *)libraryAgent {
return [ARTClientInformation libraryAgentIdentifier];
}
Expand Down
10 changes: 3 additions & 7 deletions Source/ARTProtocolMessage.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ - (id)copyWithZone:(NSZone *)zone {
return pm;
}

- (BOOL)mergeFrom:(ARTProtocolMessage *)src {
- (BOOL)mergeFrom:(ARTProtocolMessage *)src maxSize:(NSInteger)maxSize {
if (![src.channel isEqualToString:self.channel] || src.action != self.action) {
// RTL6d3
return NO;
}
if ([self mergeWouldExceedMaxSize:src.messages]) {
if ([self mergeWithMessages:src.messages wouldExceedMaxSize:maxSize]) {
// RTL6d1
return NO;
}
Expand Down Expand Up @@ -142,7 +142,7 @@ - (BOOL)clientIdsAreDifferent:(NSArray<ARTMessage*>*)messages {
}
}

- (BOOL)mergeWouldExceedMaxSize:(NSArray<ARTMessage*>*)messages {
- (BOOL)mergeWithMessages:(NSArray<ARTMessage*>*)messages wouldExceedMaxSize:(NSInteger)maxSize {
NSInteger queuedMessagesSize = 0;
for (ARTMessage *message in self.messages) {
queuedMessagesSize += [message messageSize];
Expand All @@ -152,10 +152,6 @@ - (BOOL)mergeWouldExceedMaxSize:(NSArray<ARTMessage*>*)messages {
messagesSize += [message messageSize];
}
NSInteger totalSize = queuedMessagesSize + messagesSize;
NSInteger maxSize = [ARTDefault maxMessageSize];
if (_connectionDetails.maxMessageSize) {
maxSize = _connectionDetails.maxMessageSize;
}
return totalSize > maxSize;
}

Expand Down
4 changes: 2 additions & 2 deletions Source/ARTQueuedMessage.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ - (NSString *)description {
return [self.msg description];
}

- (BOOL)mergeFrom:(ARTProtocolMessage *)msg sentCallback:(ARTCallback)sentCallback ackCallback:(ARTStatusCallback)ackCallback {
if ([self.msg mergeFrom:msg]) {
- (BOOL)mergeFrom:(ARTProtocolMessage *)msg maxSize:(NSInteger)maxSize sentCallback:(ARTCallback)sentCallback ackCallback:(ARTStatusCallback)ackCallback {
if ([self.msg mergeFrom:msg maxSize:maxSize]) {
if (sentCallback) {
[self.sentCallbacks addObject:sentCallback];
}
Expand Down
3 changes: 2 additions & 1 deletion Source/ARTRealtime.m
Original file line number Diff line number Diff line change
Expand Up @@ -1273,7 +1273,8 @@ - (void)send:(ARTProtocolMessage *)msg reuseMsgSerial:(BOOL)reuseMsgSerial sentC
else if (msg.ackRequired) {
if (self.isActive && self.options.queueMessages) {
ARTQueuedMessage *lastQueuedMessage = self.queuedMessages.lastObject; //RTL6d5
BOOL merged = [lastQueuedMessage mergeFrom:msg sentCallback:nil ackCallback:ackCallback];
NSInteger maxSize = _connection.maxMessageSize;
BOOL merged = [lastQueuedMessage mergeFrom:msg maxSize:maxSize sentCallback:nil ackCallback:ackCallback];
if (!merged) {
ARTQueuedMessage *qm = [[ARTQueuedMessage alloc] initWithProtocolMessage:msg sentCallback:sentCallback ackCallback:ackCallback];
[self.queuedMessages addObject:qm];
Expand Down
5 changes: 1 addition & 4 deletions Source/ARTRealtimeChannel.m
Original file line number Diff line number Diff line change
Expand Up @@ -1066,10 +1066,7 @@ - (BOOL)exceedMaxSize:(NSArray<ARTBaseMessage *> *)messages {
for (ARTMessage *message in messages) {
size += [message messageSize];
}
NSInteger maxSize = [ARTDefault maxMessageSize];
if (self.realtime.connection.maxMessageSize) {
maxSize = self.realtime.connection.maxMessageSize;
}
NSInteger maxSize = _realtime.connection.maxMessageSize;
return size > maxSize;
}

Expand Down
3 changes: 3 additions & 0 deletions Source/PrivateHeaders/Ably/ARTDefault+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ extern NSString *const ARTDefaultProduction;
+ (void)setConnectionStateTtl:(NSTimeInterval)value;
+ (void)setMaxMessageSize:(NSInteger)value;

+ (NSInteger)maxSandboxMessageSize;
+ (NSInteger)maxProductionMessageSize;

@end
2 changes: 1 addition & 1 deletion Source/PrivateHeaders/Ably/ARTProtocolMessage+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (readonly, nonatomic) BOOL hasBacklog;
@property (readonly, nonatomic) BOOL resumed;

- (BOOL)mergeFrom:(ARTProtocolMessage *)msg;
- (BOOL)mergeFrom:(ARTProtocolMessage *)msg maxSize:(NSInteger)maxSize;

@end

Expand Down
2 changes: 1 addition & 1 deletion Source/include/Ably/ARTQueuedMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ NS_ASSUME_NONNULL_BEGIN

- (instancetype)initWithProtocolMessage:(ARTProtocolMessage *)msg sentCallback:(nullable ARTCallback)sentCallback ackCallback:(nullable ARTStatusCallback)ackCallback;

- (BOOL)mergeFrom:(ARTProtocolMessage *)msg sentCallback:(nullable ARTCallback)sentCallback ackCallback:(nullable ARTStatusCallback)ackCallback;
- (BOOL)mergeFrom:(ARTProtocolMessage *)msg maxSize:(NSInteger)maxSize sentCallback:(nullable ARTCallback)sentCallback ackCallback:(nullable ARTStatusCallback)ackCallback;

- (ARTCallback)sentCallback;
- (ARTStatusCallback)ackCallback;
Expand Down
2 changes: 1 addition & 1 deletion Test/Tests/AuthTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1914,7 +1914,7 @@ class AuthTests: XCTestCase {
guard let error = error else {
fail("Error is nil"); done(); return
}
expect(error.message).to(contain("mismatched clientId"))
expect(error.message).to(contain("invalid clientId"))
done()
}
}
Expand Down
9 changes: 6 additions & 3 deletions Test/Tests/RealtimeClientConnectionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -168,19 +168,22 @@ class RealtimeClientConnectionTests: XCTestCase {
options.testOptions.transportFactory = TestProxyTransportFactory()
let client = ARTRealtime(options: options)
let defaultMaxMessageSize = ARTDefault.maxMessageSize()
XCTAssertEqual(defaultMaxMessageSize, 65536)
// Sandbox apps have a 16384 limit
XCTAssertEqual(defaultMaxMessageSize, 16384)
defer {
ARTDefault.setMaxMessageSize(defaultMaxMessageSize)
client.dispose()
client.close()
}
// Setting different value to check override below
ARTDefault.setMaxMessageSize(1)

waitUntil(timeout: testTimeout) { done in
client.connection.once(.connected) { _ in
let transport = client.internal.transport as! TestProxyTransport
let firstConnectionDetails = transport.protocolMessagesReceived.filter { $0.action == .connected }[0].connectionDetails
XCTAssertEqual(firstConnectionDetails!.maxMessageSize, 16384) // Sandbox apps have a 16384 limit
let maxMessageSize = transport.protocolMessagesReceived.filter { $0.action == .connected }[0].connectionDetails?.maxMessageSize
XCTAssertEqual(maxMessageSize, defaultMaxMessageSize)
XCTAssertEqual(client.connection.maxMessageSize, maxMessageSize)
done()
}
client.connect()
Expand Down
Loading