-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Rework sync config initialization #7857
Conversation
b4bbe62
to
af0ab70
Compare
8719371
to
b985477
Compare
Calculate the path from the partition value when a RLMSyncConfiguration is constructed rather than when it's set on a RLMRealmConfiguration, and change RealmSwift.SyncConfiguration to wrap a RLMSyncConfiguration rather than copying the values out. In combination, these changes make it so that we only calculate the path when the configuration is constructed, rather than every time a Realm instance is obtained.
It's basically impossible to actually safely assign to it at any point witohut it being atomic, as the reads of it typically happen on background threads.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplifying the code for RLMSyncConfiguration and get a performance boost out it, is amazing. Great PR
@@ -1,7 +1,8 @@ | |||
x.y.z Release notes (yyyy-MM-dd) | |||
============================================================= | |||
### Enhancements | |||
* None. | |||
* Greatly improve the performance of obtaining cached Realm instances in Swift |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this enhancement coming from a user issue, could be valuable to tag this here?
@@ -953,7 +953,7 @@ - (void)testFlexibleSyncInitialSubscriptionAwait { | |||
CHECK_COUNT(11, Person, realm); | |||
[ex fulfill]; | |||
}]; | |||
[self waitForExpectationsWithTimeout:10.0 handler:nil]; | |||
[self waitForExpectationsWithTimeout:30.0 handler:nil]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason for extending the timeout times in most of the server tests and the app creation?, isn't this enhancement supposed to make opening the realm faster
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests have been failing pretty consistently with timeouts due to the server being slow. All of the timeouts I bumped were ones which failed at least occasionally when using Xcode's "run tests repeatably until failure".
@@ -2624,6 +2624,13 @@ - (void)testWatchWithMatchFilterAsync { | |||
|
|||
- (NSArray<RLMObjectId *> *)insertDogDocuments:(RLMMongoCollection *)collection { | |||
__block NSArray<RLMObjectId *> *objectIds; | |||
XCTestExpectation *ex = [self expectationWithDescription:@"delete existing documents"]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aren't we cleaning all documents on every tearDown, why duplicating it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, we don't delete anything on tearDown. The sync tests use a separate partition for each test so that they don't see each others data, but these tests are accessing the collection directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does deleting all documents before inserting obscure what this function is intended for? Should the calling function just call something like deleteAllDogDocuments
and then call insertDogDocuments
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We never want to call them separately, but I guess the name should be prepareDogDocuments
or something. The thing being fixed here is that without deleting old documents the tests only work when run in a specific order and break when run in other orders due to the missing cleanup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, lets change the name to avoid confusion in the future
@@ -179,7 +179,9 @@ - (void)setInMemoryIdentifier:(NSString *)inMemoryIdentifier { | |||
|
|||
- (void)setSeedFilePath:(NSURL *)seedFilePath { | |||
_seedFilePath = seedFilePath; | |||
_config.in_memory = false; | |||
if (_seedFilePath) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this redundant, _seedFilePath
cannot be null because we just set it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is making config.seedFilePath = nil
valid.
|
||
self.customFileURL = customFileURL; | ||
return self; | ||
- (instancetype)initWithUser:(RLMUser *)user |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good job simplifying the RLMSyncConfiguration initialisation
_ = realm.configuration | ||
deleteServerFiles() | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see most of this test are PBS, I know how we build the sync configuration is pretty similar for for FLX and PBS, but we do obtain the path differently for each type of sync configuration, it could be nice to have a test using a flexible sync configuration giving that FLX is our go to sync configuration in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with Diana
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated it to test both flx and pbs and added comments for the less obvious bits in the test.
} | ||
} | ||
} | ||
_ = realm.configuration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to read the configuration at the end of this test, is this adding any value to the test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Swift (sometimes) drops references to objects after the last time they are used rather than at the end of the scope, so without this the realm may be deallocated before the actual test runs.
clientResetMode:clientResetMode | ||
notifyBeforeReset:beforeResetBlock | ||
notifyAfterReset:afterResetBlock]; | ||
partitionValue:partitionValue]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the stop policy for this particular method, wouldn't be a breaking change?, I don't know that much but RLMSyncStopPolicyImmediately maybe makes sense during a client reset
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SessionStopPolicy isn't part of the public API, and one of the initializers using a different stop policy from the rest was just a bug. This isn't used during a client reset; it's just a convenience initializer for setting the callbacks while initializing a configuration, and that clearly shouldn't result in an unrelated property being set differently.
@@ -373,7 +368,7 @@ - (RLMSyncConfiguration *)syncConfiguration { | |||
if (!_config.sync_config) { | |||
return nil; | |||
} | |||
return [[RLMSyncConfiguration alloc] initWithRawConfig:*_config.sync_config]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need to initialise the RLMSyncConfiguration every time we are reading the syncConfiguration, doesn't RLMSyncConfiguration holds a reference to the SyncConfig from core
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RLMRealmConfiguration does not hold onto a RLMSyncConfiguration instance, so we have to create the obj-c wrapper on each access. IIRC retaining it has awkward reference cycle issues.
Calculate the path from the partition value when a RLMSyncConfiguration is constructed rather than when it's set on a RLMRealmConfiguration, and change RealmSwift.SyncConfiguration to wrap a RLMSyncConfiguration rather than copying the values out. In combination, these changes make it so that we only calculate the path when the configuration is constructed, rather than every time a Realm instance is obtained. The internal initializers for RLMSyncConfiguration have gotten pretty unwieldy over the years so I refactored that a bit, which shouldn't have any effect on the public API.
The newly added perf tests run in ~350ms each on master and <1ms with these changes.
After upgrading to macOS 12.4 building node 13 stopped working for me due it one of the many subcomponents requiring python2, so I switched the baas tests to using the latest LTS version of node.