diff --git a/Signal/AppLaunch/AppDelegate.swift b/Signal/AppLaunch/AppDelegate.swift index 7c4ba22d46..c219f42aa1 100644 --- a/Signal/AppLaunch/AppDelegate.swift +++ b/Signal/AppLaunch/AppDelegate.swift @@ -673,6 +673,15 @@ final class AppDelegate: UIResponder, UIApplicationDelegate { ).scheduleProfileFetches() } + let groupV2Updates = SSKEnvironment.shared.groupV2UpdatesRef + cron.schedulePeriodically( + uniqueKey: .fetchStaleGroup, + approximateInterval: .day, + mustBeRegistered: true, + mustBeConnected: true, + operation: { try await groupV2Updates.autoRefreshGroup() }, + ) + appReadiness.runNowOrWhenAppDidBecomeReadyAsync { Task.detached(priority: .low) { YDBStorage.deleteYDBStorage() diff --git a/SignalServiceKit/Groups/GroupV2UpdatesImpl.swift b/SignalServiceKit/Groups/GroupV2UpdatesImpl.swift index 88fba91a21..bc7827607e 100644 --- a/SignalServiceKit/Groups/GroupV2UpdatesImpl.swift +++ b/SignalServiceKit/Groups/GroupV2UpdatesImpl.swift @@ -6,7 +6,7 @@ import Foundation public import LibSignalClient -public class GroupV2UpdatesImpl { +public class GroupV2UpdatesImpl: GroupV2Updates { // This tracks the last time that groups were updated to the current // revision. @@ -18,26 +18,18 @@ public class GroupV2UpdatesImpl { init(appReadiness: AppReadiness) { SwiftSingletons.register(self) - - appReadiness.runNowOrWhenMainAppDidBecomeReadyAsync { - Task { await self.autoRefreshGroupOnLaunch() } - } } // MARK: - - // On launch, we refresh a few randomly-selected groups. - private func autoRefreshGroupOnLaunch() async { + // On launch, we refresh a randomly-selected group. + public func autoRefreshGroup() async throws(CancellationError) { let tsAccountManager = DependenciesBridge.shared.tsAccountManager guard tsAccountManager.registrationStateWithMaybeSneakyTransaction.isRegistered else { return } - do throws(CancellationError) { - try await SSKEnvironment.shared.messageProcessorRef.waitForFetchingAndProcessing() - } catch { - return - } + try await SSKEnvironment.shared.messageProcessorRef.waitForFetchingAndProcessing() guard let groupInfoToRefresh = Self.findGroupToAutoRefresh() else { // We didn't find a group to refresh; abort. @@ -48,15 +40,15 @@ public class GroupV2UpdatesImpl { let groupSecretParams = groupInfoToRefresh.groupSecretParams if let lastRefreshDate = groupInfoToRefresh.lastRefreshDate { let formattedDays = String(format: "%.1f", -lastRefreshDate.timeIntervalSinceNow / TimeInterval.day) - Logger.info("Auto-refreshing group: \(groupId) which hasn't been refreshed in \(formattedDays) days.") + Logger.info("auto-refreshing group: \(groupId) which hasn't been refreshed in \(formattedDays) days") } else { - Logger.info("Auto-refreshing group: \(groupId) which has never been refreshed.") + Logger.info("auto-refreshing group: \(groupId) which has never been refreshed") } do { try await self.refreshGroup(secretParams: groupSecretParams) } catch GroupsV2Error.localUserNotInGroup { - Logger.warn("Can't auto-refresh group unless we're a member") + Logger.warn("can't auto-refresh group unless we're a member") } catch { owsFailDebugUnlessNetworkFailure(error) } @@ -70,8 +62,7 @@ public class GroupV2UpdatesImpl { private static func findGroupToAutoRefresh() -> GroupInfo? { // Enumerate the all v2 groups, trying to find the "best" one to refresh. - // The "best" is the group that hasn't been refreshed in the longest - // time. + // The "best" is the group that hasn't been refreshed in the longest time. SSKEnvironment.shared.databaseStorageRef.read { transaction in var groupInfoToRefresh: GroupInfo? TSGroupThread.anyEnumerate( @@ -131,11 +122,6 @@ public class GroupV2UpdatesImpl { return groupInfoToRefresh } } -} - -// MARK: - GroupV2UpdatesSwift - -extension GroupV2UpdatesImpl: GroupV2Updates { public func updateGroupWithChangeActions( groupId: GroupIdentifier, diff --git a/SignalServiceKit/Groups/GroupsV2.swift b/SignalServiceKit/Groups/GroupsV2.swift index 8c3dcc04ef..6579424d22 100644 --- a/SignalServiceKit/Groups/GroupsV2.swift +++ b/SignalServiceKit/Groups/GroupsV2.swift @@ -202,6 +202,8 @@ public struct GroupsV2BuiltGroupChange { // MARK: - public protocol GroupV2Updates { + func autoRefreshGroup() async throws(CancellationError) + func refreshGroupImpl( secretParams: GroupSecretParams, spamReportingMetadata: GroupUpdateSpamReportingMetadata, @@ -612,6 +614,10 @@ public class MockGroupsV2: GroupsV2 { // MARK: - public class MockGroupV2Updates: GroupV2Updates { + public func autoRefreshGroup() async throws(CancellationError) { + owsFail("Not implemented.") + } + public func refreshGroupImpl( secretParams: GroupSecretParams, spamReportingMetadata: GroupUpdateSpamReportingMetadata, diff --git a/SignalServiceKit/Jobs/Cron.swift b/SignalServiceKit/Jobs/Cron.swift index e4a9c82d56..5c5b0db95a 100644 --- a/SignalServiceKit/Jobs/Cron.swift +++ b/SignalServiceKit/Jobs/Cron.swift @@ -65,6 +65,7 @@ public class Cron { case checkUsername case cleanUpMessageSendLog case cleanUpViewOnceMessages + case fetchStaleGroup } init(