-
Notifications
You must be signed in to change notification settings - Fork 199
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
Initial sync startup/3-way merge #238
Conversation
- Initial implementation of InitialSyncOrchestrator, integrated with ReconciliationQueue to apply incoming sync query results - Added a buffer queue for incoming remote events to ReconciliationQueue, so remote API sync can be turned off indpendently of applying mutations from sync queries - Made CancelAwareBlockOperation a standalone class - Model extensions - Change ModelSchema+Syncable to ModelSchema+Attributes - Added 'ModelSchema.isSystem' convenience getter - Change 'hasSyncableModels' to look for the existence of any non-system models; all models are considered syncable by default (no local model support at launch) - Added ModelGraphs to track Model connection dependencies for initial sync - Made AtomicValue public so it can be used in plugins; added convenience methods for RangeReplaceableCollection - Removed isSyncable schema attribute in favor of designating all non-system models as syncable; added buffer queue for incoming subscription event submission to reconciliation queue; refactoring & renaming - Added 'DataStore.internalOperation' to contain errors about nil weak references being unavailable - Added convenience DataStoreError constructor for missing reconciliation queue
- Fix some linting warnings - Minor test cleanup - Added responders to MockAPICategoryPlugin to let us invoke callback of methods - Added unit tests for InitialSyncOperation happy path
…concrete type - InitialSyncOrchestrator unit tests
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.
Self review to set checkpoint
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.
leaving some initial comments and opening issue for API category's Model based GraphQL APIs dependency on ModelRegistry's isSyncable method #239
AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/InitialSync/InitialSyncOperation.swift
Show resolved
Hide resolved
AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/InitialSync/InitialSyncOperation.swift
Show resolved
Hide resolved
if #available(iOS 13, *) { | ||
let syncEngine = isSyncEnabled ? try? RemoteSyncEngine(storageAdapter: storageAdapter) : nil | ||
self.init(storageAdapter: storageAdapter, syncEngine: syncEngine, isSyncEnabled: isSyncEnabled) | ||
self.init(storageAdapter: storageAdapter, syncEngine: syncEngine) | ||
} else { | ||
self.init(storageAdapter: storageAdapter, syncEngine: nil, isSyncEnabled: isSyncEnabled) | ||
self.init(storageAdapter: storageAdapter, syncEngine: 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.
is there a way to check if Amplify.API is configured here? if it's iOS13 && Amplify.API.isConfigured then create a RemoveSyncEngine with storageAdapter and Amplify.API. I would have imagined RemoteSyncEngine to always need an API when being constructed.
I don't have a real good use case to expose isConfigured
at the Category level except that whenever pluginKey's do not match the plugin's key, then the plugin that was added to Amplify doesn't get called on the plugin's configure() method, which developer will then find out it is not configured at plugin's API calls. And also in this case where plugins are seeing if another plugin is configured. DataStore checking if API for sync, API checking for DataStore for Model based GraphQL calls,
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.
is there a way to check if Amplify.API is configured here?
Not yet, but it's something we need to figure out. Currently I'm of two minds:
- Expose an explicit
isConfigured
check on the category, as you discuss, and note it asinternal
in the docs. I also can't think of a good customer-facing use case, but I don't know of a way to expose an internal property across modules without resorting to Objective-C. - Do away with
isConfigured
checks altogether except if the customer adds a plugin. Other categories would be fulfilled by no-op operations that invoke errors on their callbacks as soon as they're created. That adds more runtime complexity to the Amplify core, though.
We're going to have to answer this question once and for all, and soon, since our cross-category use cases are going to grow: Predictions->Storage (upload an image to Storage so Predictions can identify entities in it); or DataStore->Storage (complex object support); or Analytics as a "middleware" plugin that intercepts Hub events and auto-logs messages.
...tore/AWSDataStoreCategoryPlugin/Sync/MutationSync/MutationEvent/MutationEventPublisher.swift
Show resolved
Hide resolved
...oreCategoryPlugin/Sync/MutationSync/OutgoingMutationQueue/SyncMutationToCloudOperation.swift
Show resolved
Hide resolved
AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/Core/ModelGraphsTests.swift
Show resolved
Hide resolved
AmplifyPlugins/DataStore/AWSDataStoreCategoryPluginTests/TestSupport/SyncEngineTestBase.swift
Show resolved
Hide resolved
@@ -28,290 +28,296 @@ | |||
/* End PBXAggregateTarget section */ | |||
|
|||
/* Begin PBXBuildFile section */ | |||
004DE85F3AE8FFE0816925652FFFBB75 /* AWSCognitoCredentialsProvider+Extension.h in Headers */ = {isa = PBXBuildFile; fileRef = 953E533AB3626686BC0DCFEE4DCDBCC9 /* AWSCognitoCredentialsProvider+Extension.h */; settings = {ATTRIBUTES = (Public, ); }; }; |
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 typically avoided commiting this file, as well as the .lock files... do we need to commit these files?
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 should have a team discussion about this. Guidance from CocoaPods (and my personal preference) is that we should commit Pods, manifest & lock to the repo, as they are necessary for non-CocoaPods systems (e.g., Carthage) to build. However, we haven't propagated that pattern into the plugin folders, and I'd like to understand other points of view.
AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/RemoteSyncEngine.swift
Show resolved
Hide resolved
...CategoryPlugin/Sync/SubscriptionSync/ReconcileAndLocalSave/AWSModelReconciliationQueue.swift
Show resolved
Hide resolved
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.
Responding to PR comments
AmplifyPlugins/DataStore/AWSDataStoreCategoryPlugin/Sync/InitialSync/InitialSyncOperation.swift
Show resolved
Hide resolved
if #available(iOS 13, *) { | ||
let syncEngine = isSyncEnabled ? try? RemoteSyncEngine(storageAdapter: storageAdapter) : nil | ||
self.init(storageAdapter: storageAdapter, syncEngine: syncEngine, isSyncEnabled: isSyncEnabled) | ||
self.init(storageAdapter: storageAdapter, syncEngine: syncEngine) | ||
} else { | ||
self.init(storageAdapter: storageAdapter, syncEngine: nil, isSyncEnabled: isSyncEnabled) | ||
self.init(storageAdapter: storageAdapter, syncEngine: 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.
is there a way to check if Amplify.API is configured here?
Not yet, but it's something we need to figure out. Currently I'm of two minds:
- Expose an explicit
isConfigured
check on the category, as you discuss, and note it asinternal
in the docs. I also can't think of a good customer-facing use case, but I don't know of a way to expose an internal property across modules without resorting to Objective-C. - Do away with
isConfigured
checks altogether except if the customer adds a plugin. Other categories would be fulfilled by no-op operations that invoke errors on their callbacks as soon as they're created. That adds more runtime complexity to the Amplify core, though.
We're going to have to answer this question once and for all, and soon, since our cross-category use cases are going to grow: Predictions->Storage (upload an image to Storage so Predictions can identify entities in it); or DataStore->Storage (complex object support); or Analytics as a "middleware" plugin that intercepts Hub events and auto-logs messages.
ReconciliationQueue to apply incoming sync query results
remote API sync can be turned off independently of applying mutations from
sync queries
models; all models are considered syncable by default (no local model support
at launch)
methods for RangeReplaceableCollection
models as syncable
submission to reconciliation queue
references being unavailable
Description of changes:
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.