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

refactor: integrate new initial sync - WPB-10801 #2527

Open
wants to merge 22 commits into
base: develop
Choose a base branch
from

Conversation

johnxnguyen
Copy link
Collaborator

@johnxnguyen johnxnguyen commented Feb 12, 2025

TaskWPB-10801 [iOS] Integrate new slow sync

Issue

In this PR we integrate the new initial sync by:

  • initializing and injecting SyncAgent into the ZMUserSession
  • replace calls to the SyncStatus with calls to SyncAgent

If the developer flag newInitialSync is off (the default), then the SyncAgent will execute legacy code paths via the SyncStatus. If it is on, it will run the new initial sync, then continue with the legacy incremental sync.

Integrating the new incremental sync will follow in a subsequent PR.

Testing

To check the legacy code paths are still in tact, install the app fresh and log in and use the app as normal. To test the new code paths, enabled the flag via the developer menu.

Issues to look for include infinite sync, getting stuck when logging in or registering a client (including deleting a client).


Checklist

  • Title contains a reference JIRA issue number like [WPB-XXX].
  • Description is filled and free of optional paragraphs.
  • Adds/updates automated tests.

UI accessibility checklist

If your PR includes UI changes, please utilize this checklist:

  • Make sure you use the API for UI elements that support large fonts.
  • All colors are taken from WireDesign.ColorTheme or constructed using WireDesign.BaseColorPalette.
  • New UI elements have Accessibility strings for VoiceOver.

var synchronizationState: SynchronizationState { get }
var operationState: OperationState { get }
var clientRegistrationDelegate: ClientRegistrationDelegate { get }
var requestCancellation: ZMRequestCancellation { get }

func requestResyncResources()
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was dead.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Changes here are for injecting dependencies necessary to create the SyncAgent.

Comment on lines -111 to -118
public func requestResyncResources() {
syncStatus.resyncResources()
}

public func requestQuickSync() {
syncStatus.forceQuickSync()
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This code was dead

RequestAvailableNotification.notifyNewRequestsAvailable(nil)
log("slow sync")
syncStateDelegate?.didStartSlowSync()
managedObjectContext.perform { [weak self] in
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Previously, these code paths were always executed on the sync context (which is what managedObjectContext is). Now these methods may be called from async methods, so we need to ensure we switch to the right queue otherwise we'll get some core data errors.

Comment on lines -773 to -778
// MARK: Network

public func requestResyncResources() {
applicationStatusDirectory.requestResyncResources()
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was dead code

try await mlsService.repairOutOfSyncConversations()
} catch {
WireLogger.mls.error("Repairing out of sync conversations failed: \(error)")
syncContext.perform { [weak self] in
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Before we (bravely) assumed that this method would be invoked on the sync context, now it's not always true, so best to switch to it explicitly.

WireLogger.sync.debug("did finish quick sync")
processEvents()
private func didFinishIncrementalSync() {
syncContext.perform { [weak self] in
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Changes here are to switch to the sync context.

Comment on lines -1186 to -1193
if userClient.hasRegisteredMLSClient {
// Before the client was registered as an MLS client,
// They wouldn't have been able to migrate any conversations from Proteus to MLS.
// So we perform a slow sync to sync the conversations. This will ensure that
// the message protocol of each conversation is up-to-date.
// The client will then join any MLS groups they haven't joined yet.
syncStatus.forceSlowSync()
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I deleted this because now we always trigger an initial sync (a few lines below)

@netbe netbe self-requested a review February 12, 2025 15:04
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I realized that I was missing a step in the pull resources sync to fetch the mls status, changes here are adding it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Here we add the missing step I mentioned earlier.

Copy link
Collaborator

@netbe netbe left a comment

Choose a reason for hiding this comment

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

looks good, adding some thoughts and concerns about processing buffered events in legacy

} else if context.readMigrationNeedsSyncResourcesFlag() {
userSession.syncStatus.resyncResources()
userSession.triggerResourceSync()
Copy link
Collaborator

Choose a reason for hiding this comment

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

nitpic: wouldn't it be?

Suggested change
userSession.triggerResourceSync()
userSession.triggerResourcesSync()


Task {
do {
// Only sync if there is a self client, otherwise we'll perform a initial sync
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// Only sync if there is a self client, otherwise we'll perform a initial sync
// Only sync if there is a self client, otherwise we'll perform an initial sync

}
}

public func triggerResourceSync() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
public func triggerResourceSync() {
public func triggerResourcesSync() {

.init(title: "Resync resources", action: resyncResources),
.init(title: "Break next quick sync", action: breakNextQuickSync),
.init(title: "Trigger incremental sync", action: triggerIncrementalSync),
.init(title: "Trigger resource sync", action: triggerResourceSync),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
.init(title: "Trigger resource sync", action: triggerResourceSync),
.init(title: "Trigger resources sync", action: triggerResourceSync),

Comment on lines 949 to 974
func syncAgentDidStartInitialSync(_ syncAgent: SyncAgent) {
didStartInitialSync()
}

func syncAgentDidFinishInitialSync(_ syncAgent: SyncAgent) {
didFinishInitialSync()
}

func syncAgentDidStartLegacyInitialSync(_ syncAgent: SyncAgent) {
didStartInitialSync()
}

func syncAgentDidFinishLegacyInitialSync(_ syncAgent: SyncAgent) {
didFinishInitialSync()
}

func syncAgentDidStartLegacyIncrementalSync(_ syncAgent: SyncAgent) {
didStartIncrementalSync()
}

public func didStartSlowSync() {
func syncAgentDidFinishLegacyIncrementalSync(_ syncAgent: SyncAgent) {
didFinishIncrementalSync()
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

thought: might be good to make these methods async as we rework later the codebase we will be able to take advantage of it

syncContext.perform { [weak self] in
guard let self else { return }
WireLogger.sync.debug("did finish incremental sync")
processEvents()
Copy link
Collaborator

Choose a reason for hiding this comment

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

issue: here we process buffered events in legacy code, isn't the new sync handling those?

suggestion: separate the implementation of didFinishIncrementalSync in distinct methods for legacy and new code. That way we can also really wait for the async function in the WaitingGroupTask

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not yet, this PR is only replacing the slow sync. I was planning to add the new quick sync in a next PR, but I could also add it here

Copy link
Collaborator

Choose a reason for hiding this comment

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

as long as we don't forget, it's fine in the other PR. I'll approve as it is now

Copy link
Collaborator

@netbe netbe left a comment

Choose a reason for hiding this comment

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

LGTM;)

@johnxnguyen johnxnguyen marked this pull request as ready for review February 12, 2025 16:45
Copy link
Contributor

github-actions bot commented Feb 12, 2025

Test Results

    1 files      2 suites   2m 8s ⏱️
1 789 tests 1 763 ✅ 26 💤 0 ❌
1 799 runs  1 773 ✅ 26 💤 0 ❌

Results for commit 94256c5.

♻️ This comment has been updated with latest results.

@datadog-wireapp
Copy link

datadog-wireapp bot commented Feb 12, 2025

Datadog Report

Branch report: refactor/integrate-sync-agent-wpb-10801
Commit report: 56a86c8
Test service: wire-ios-mono

✅ 0 Failed, 1687 Passed, 26 Skipped, 2m 8.16s Total Time

@johnxnguyen johnxnguyen changed the base branch from release/cycle-3.118 to develop February 14, 2025 08:04
@johnxnguyen johnxnguyen changed the base branch from develop to release/cycle-3.118 February 14, 2025 08:04
@johnxnguyen johnxnguyen force-pushed the refactor/integrate-sync-agent-wpb-10801 branch from 94256c5 to 6563468 Compare February 14, 2025 11:11
@johnxnguyen johnxnguyen changed the base branch from release/cycle-3.118 to develop February 14, 2025 11:14
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.

2 participants