-
Notifications
You must be signed in to change notification settings - Fork 0
Refactor FXIOS-13122 [Swift 6] Remove @Sendable from closures marked as @MainActor #20
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
base: coderabbit_combined_20260121_augment_sentry_coderabbit_1_base_refactor_fxios-13122_swift_6_remove_sendable_from_closures_marked_as_mainactor_pr208
Are you sure you want to change the base?
Refactor FXIOS-13122 [Swift 6] Remove @Sendable from closures marked as @MainActor #20
Conversation
WalkthroughThis PR systematically removes the Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~35 minutes The changes follow a highly repetitive pattern (removing Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Comment |
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.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
firefox-ios/Client/Frontend/Browser/BrowserViewController/Extensions/BrowserViewController+WebViewDelegates.swift (1)
1329-1352: Inconsistent main-thread dispatch inhandleServerTrust.There's an inconsistency in how
completionHandleris invoked:
- Line 1343: Called directly inside
dispatchQueue.asyncwithout ensuring main thread- Line 1349: Wrapped in
ensureMainThreadSince
completionHandleris@MainActor, both call sites should consistently useensureMainThreadto avoid relying on implicit actor hop behavior.Suggested fix for consistency
guard let trust = challenge.protectionSpace.serverTrust, let cert = SecTrustCopyCertificateChain(trust) as? [SecCertificate], self.profile.certStore.containsCertificate(cert[0], forOrigin: origin) else { - completionHandler(.performDefaultHandling, nil) + ensureMainThread { + completionHandler(.performDefaultHandling, nil) + } return }
🤖 Fix all issues with AI agents
In `@firefox-ios/Client/Utils/MainThreadThrottler.swift`:
- Around line 25-29: In throttle(completion:) the guard must run before updating
lastExecutionTime so the elapsed-time check uses the previous timestamp; move
the assignment to lastExecutionTime to after the guard (or compute now first and
compare against the existing lastExecutionTime) and only update
lastExecutionTime when you actually allow execution, then
DispatchQueue.main.async(execute: completion) as before; reference symbols:
throttle(completion:), lastExecutionTime, threshold, and
DispatchQueue.main.async.
🧹 Nitpick comments (1)
firefox-ios/Client/Frontend/Widgets/PhotonActionSheet/SingleActionViewModel.swift (1)
97-117: Note:copy()omitscustomRenderandcustomHeight.This is pre-existing behavior unrelated to the current refactor, but worth noting: the
copy()function only propagatestapHandlerbut notcustomRenderorcustomHeight. If this is intentional, consider adding a brief comment; otherwise, these properties could be included for completeness.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (40)
BrowserKit/Sources/Common/Utilities/DispatchQueueHelper.swiftBrowserKit/Sources/Common/Utilities/DispatchQueueInterface.swiftBrowserKit/Sources/MenuKit/MenuElement.swiftBrowserKit/Sources/Redux/Reducer.swiftBrowserKit/Sources/Shared/UIDeviceDetails.swiftBrowserKit/Sources/WebEngine/WKWebview/WKEngineWebView.swiftBrowserKit/Tests/WebEngineTests/Mock/MockWKEngineWebView.swiftfirefox-ios/Client/AccountSyncHandler.swiftfirefox-ios/Client/Application/WebServer.swiftfirefox-ios/Client/Frontend/AuthenticationManager/AppAuthenticator.swiftfirefox-ios/Client/Frontend/Autofill/CreditCard/CreditCardSettingsView/CreditCardInputViewModel.swiftfirefox-ios/Client/Frontend/Browser/BrowserViewController/Actions/WebContextMenuActionsProvider.swiftfirefox-ios/Client/Frontend/Browser/BrowserViewController/Extensions/BrowserViewController+WebViewDelegates.swiftfirefox-ios/Client/Frontend/Browser/BrowserViewController/WebEngineIntegration/BrowserWebUIDelegate.swiftfirefox-ios/Client/Frontend/Browser/DownloadHelper/DownloadHelper.swiftfirefox-ios/Client/Frontend/Browser/MainMenuActionHelper.swiftfirefox-ios/Client/Frontend/Browser/RelayController.swiftfirefox-ios/Client/Frontend/Browser/SearchEngines/SearchEngineProvider.swiftfirefox-ios/Client/Frontend/Browser/SearchEngines/SearchEnginesManager.swiftfirefox-ios/Client/Frontend/Browser/TabScrollController/TabProviderAdapter.swiftfirefox-ios/Client/Frontend/Home/Homepage/SectionHeader/LabelButtonHeaderView.swiftfirefox-ios/Client/Frontend/Library/Bookmarks/Legacy/BookmarksPanelViewModel.swiftfirefox-ios/Client/Frontend/Library/ClearHistorySheetProvider.swiftfirefox-ios/Client/Frontend/Library/HistoryPanel/HistoryPanelViewModel.swiftfirefox-ios/Client/Frontend/Onboarding/Models/UpdateViewModel.swiftfirefox-ios/Client/Frontend/PasswordManagement/PasswordManagerViewModel.swiftfirefox-ios/Client/Frontend/Settings/PasswordDetailViewController.swiftfirefox-ios/Client/Frontend/Widgets/PhotonActionSheet/SingleActionViewModel.swiftfirefox-ios/Client/TabManagement/Tab.swiftfirefox-ios/Client/Utils/MainThreadThrottler.swiftfirefox-ios/Extensions/ShareTo/InitialViewController.swiftfirefox-ios/RustFxA/FirefoxAccountSignInViewController.swiftfirefox-ios/RustFxA/FxAWebViewController.swiftfirefox-ios/Storage/Queue.swiftfirefox-ios/Storage/SQL/SQLiteQueue.swiftfirefox-ios/firefox-ios-tests/Tests/ClientTests/Frontend/Homepage/Mock/MockThrottler.swiftfirefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockAppAuthenticator.swiftfirefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockProfile.swiftfirefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockTabProviderProtocol.swiftfirefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockTabWebView.swift
🧰 Additional context used
🧬 Code graph analysis (7)
firefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockTabWebView.swift (1)
firefox-ios/Client/TabManagement/Tab.swift (1)
getSessionCookies(858-860)
firefox-ios/firefox-ios-tests/Tests/ClientTests/Frontend/Homepage/Mock/MockThrottler.swift (1)
firefox-ios/Client/Utils/MainThreadThrottler.swift (1)
throttle(25-29)
BrowserKit/Sources/Common/Utilities/DispatchQueueHelper.swift (1)
BrowserKit/Sources/Common/Utilities/DispatchQueueInterface.swift (2)
ensureMainThread(38-48)async(24-29)
firefox-ios/Storage/Queue.swift (1)
firefox-ios/Storage/SQL/SQLiteQueue.swift (1)
getQueuedTabs(24-34)
firefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockAppAuthenticator.swift (1)
firefox-ios/Client/Frontend/AuthenticationManager/AppAuthenticator.swift (1)
getAuthenticationState(29-46)
firefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockProfile.swift (1)
firefox-ios/Storage/SQL/SQLiteQueue.swift (1)
getQueuedTabs(24-34)
firefox-ios/Client/TabManagement/Tab.swift (1)
firefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockTabWebView.swift (1)
getSessionCookies(112-114)
🔇 Additional comments (60)
firefox-ios/Client/Frontend/Home/Homepage/SectionHeader/LabelButtonHeaderView.swift (1)
95-100: LGTM — signature change matches PR intent.
Removing@Sendablewhile keeping@MainActoris consistent with Swift 6 cleanup and doesn’t affect call sites here.firefox-ios/Extensions/ShareTo/InitialViewController.swift (1)
98-108: LGTM —@Sendableremoval is safe here.
@MainActorremains and the implementation still marshals to the main queue, so dropping@Sendabledoesn’t introduce new risks.firefox-ios/Client/Frontend/PasswordManagement/PasswordManagerViewModel.swift (2)
83-84: LGTM:@MainActor-onlycompletion is appropriate here.
162-163: LGTM: completion closure aligns with MainActor isolation.firefox-ios/Client/Frontend/Browser/SearchEngines/SearchEngineProvider.swift (1)
8-8: LGTM —@MainActorcompletion remains isolated.No concerns with removing
@Sendablehere.firefox-ios/Client/Frontend/Browser/SearchEngines/SearchEnginesManager.swift (1)
278-278: LGTM — completion still runs on MainActor.Signature change is consistent with the PR goal.
firefox-ios/RustFxA/FirefoxAccountSignInViewController.swift (1)
305-305: LGTM —@Sendableremoval is consistent with@MainActorisolation.firefox-ios/Client/Frontend/Browser/BrowserViewController/Actions/WebContextMenuActionsProvider.swift (1)
30-41: LGTM! Clean Swift 6 concurrency refactor.The removal of
@Sendablefrom@MainActor-isolated closures is correct. In Swift 6, combining@Sendablewith@MainActoris redundant since actor isolation already constrains how the closure can be used. The changes:
addOpenInNewTab/addOpenInNewPrivateTab: TheaddTabclosures are properly main-actor isolated.addSaveImage: ThewriteToPhotoAlbumclosure correctly removes@SendablewhilegetImageData's inner callback appropriately retains@Sendablesince it's not actor-isolated.Also applies to: 43-54, 161-184
firefox-ios/RustFxA/FxAWebViewController.swift (1)
158-179: LGTM!The removal of
@Sendablefrom thedecisionHandlerclosure parameter is correct for Swift 6 compatibility. Since the closure is already annotated with@MainActor, it's confined to the main actor, making@Sendableredundant. The method implementation correctly callsdecisionHandlerin all code paths, and the@preconcurrency import WebKitat line 5 appropriately handles backward compatibility.firefox-ios/Client/Frontend/Library/ClearHistorySheetProvider.swift (1)
23-25: LGTM! Consistent removal of@Sendablefrom@MainActorclosures.The removal of
@Sendableacross all four method signatures (showClearRecentHistory,setupActions,addDeleteSomeData,addDeleteEverythingOption) is correct for Swift 6 compatibility. Since the class is already@MainActorand the closures are explicitly marked@MainActor, the@Sendableannotation is redundant—@MainActorisolation provides the necessary thread-safety guarantees.Also applies to: 52-54, 61-63, 86-88
firefox-ios/Client/Frontend/Widgets/PhotonActionSheet/SingleActionViewModel.swift (2)
44-56: LGTM! Correct Swift 6 refactoring.Removing
@Sendablefrom@MainActorclosures is appropriate. In Swift 6,@MainActor-isolated closures are implicitlySendabledue to their actor isolation, making the explicit annotation redundant. The struct'sSendableconformance remains valid.
74-76: Initializer parameters correctly updated.The parameter types now match the corresponding property types, maintaining consistency throughout the struct.
firefox-ios/Client/Frontend/Browser/RelayController.swift (1)
10-10: LGTM!Removing
@SendablefromRelayPopulateCompletionis appropriate since the closure is exclusively used within@MainActor-isolated contexts (theRelayControllerclass itself is@MainActor-isolated). The completion handlers are invoked on the main actor, so@Sendableis unnecessary.BrowserKit/Sources/Shared/UIDeviceDetails.swift (1)
38-50: LGTM!Removing
@Sendablefrom theworkclosure parameter is correct. The closure is executed synchronously viaMainActor.assumeIsolatedorDispatchQueue.main.sync, meaning it never crosses isolation boundaries asynchronously. TheT: Sendableconstraint on the return type is sufficient to ensure the result can be safely returned.firefox-ios/Client/Frontend/Library/HistoryPanel/HistoryPanelViewModel.swift (1)
130-158: LGTM!Removing
@Sendablefrom theperformSearchcompletion is appropriate. The completion is always invoked withinMainActor.assumeIsolatedafter dispatching to.mainqueue (line 137), ensuring main-actor isolation without requiring@Sendable.Note that
reloadData(line 95) andfetchData(line 214) correctly retain@Sendableon their closures since those are called from background contexts (DispatchQueue.global()).firefox-ios/Client/AccountSyncHandler.swift (1)
19-29: LGTM!Removing
@Sendablefrom theactionclosure is correct. TheDebouncerclass is@MainActor-isolated, so theTaskcreated on line 24 inherits this isolation. The closure executes entirely within the main actor context and doesn't cross isolation boundaries.firefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockTabWebView.swift (1)
112-114: LGTM!The
MockTab.getSessionCookiesoverride correctly matches the updated signature inTab.swift(shown in relevant snippets). Both use@MainActor@escaping`` without@Sendable, maintaining consistency between the production code and test mock.firefox-ios/Client/Frontend/Onboarding/Models/UpdateViewModel.swift (1)
76-81: LGTM!Removing
@Sendablefrom thecompletionparameter is appropriate. The closure is invoked viaensureMainThread, guaranteeing execution on the main actor. Since the closure doesn't cross isolation boundaries,@Sendableis unnecessary.BrowserKit/Sources/Redux/Reducer.swift (1)
9-9: LGTM!Removing
@Sendablefrom the@MainActor-isolatedReducertypealias is correct for Swift 6 compatibility. Since reducers are designed to run exclusively on the main actor for state management, the@Sendableconstraint was redundant.firefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockProfile.swift (1)
93-98: LGTM!The mock implementation correctly aligns with the updated
TabQueueprotocol signature. TheTask {@mainactorin ... }dispatch pattern properly ensures main-actor execution for the completion handler.firefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockTabProviderProtocol.swift (1)
15-15: LGTM!Appropriate change. Since
MockTabProviderProtocolis already@MainActor-isolated (line 9), the callback will only be invoked from the main actor context, making@Sendableunnecessary.firefox-ios/Storage/SQL/SQLiteQueue.swift (1)
24-34: LGTM!The implementation correctly aligns with the updated
TabQueueprotocol. The use of.uponQueue(.main)combined withMainActor.assumeIsolatedproperly bridges GCD-based main queue execution to Swift's actor model, as noted in the existing FXIOS-13228 comment.firefox-ios/Storage/Queue.swift (1)
8-12: LGTM!The protocol change appropriately removes
@Sendablewhile preserving@MainActorisolation on the completion handler. TheTabQueueprotocol itself remainsSendable, correctly allowing instances to be passed across concurrency domains while ensuring completion callbacks execute on the main actor.firefox-ios/Client/Application/WebServer.swift (2)
18-18: Clarify intent:finalmodifier removed from class declaration.The removal of
finalis a separate change from the@Sendablerefactor. Removingfinalallows subclassing ofWebServer, which may have implications for the singleton pattern used at line 19 and the thread-safety concerns noted in the FIXME comment.Was this removal intentional? If subclassing is not required, consider keeping
finalto prevent unintended inheritance and enable compiler optimizations.
55-84: LGTM on the@Sendableremoval from the handler closure.The change correctly removes
@Sendablefrom the outerhandlerclosure while retaining it on the innerresponseCompletion. This is appropriate because:
- The
handleris explicitly dispatched viaensureMainThread(line 76), so@MainActorisolation is sufficient- The
responseCompletioncorrectly keeps@Sendablesince it must be callable from any context back to GCDWebServerfirefox-ios/Client/Frontend/Library/Bookmarks/Legacy/BookmarksPanelViewModel.swift (1)
118-122: LGTM.Signature update looks consistent with the refactor scope.
firefox-ios/Client/Frontend/Settings/PasswordDetailViewController.swift (1)
402-415: LGTM.No behavioral changes; aligns with the PR’s
@Sendableremoval.firefox-ios/Client/Frontend/Browser/TabScrollController/TabProviderAdapter.swift (2)
8-15: LGTM.Protocol change is clear and consistent.
32-35: LGTM.Adapter remains aligned with the protocol update.
BrowserKit/Sources/MenuKit/MenuElement.swift (2)
20-20: LGTM.Public API change matches the refactor intent.
37-37: LGTM.Initializer signature is consistent with the property update.
firefox-ios/Client/Frontend/Autofill/CreditCard/CreditCardSettingsView/CreditCardInputViewModel.swift (1)
258-260: LGTM.Signature update is consistent with the rest of the refactor.
firefox-ios/Client/Frontend/Browser/DownloadHelper/DownloadHelper.swift (1)
64-66: LGTM.Signature update is straightforward and consistent.
BrowserKit/Sources/WebEngine/WKWebview/WKEngineWebView.swift (2)
74-79: LGTM - Protocol signature correctly updated.The removal of
@Sendablefrom thecompletionHandlerclosure is appropriate since the protocol is already marked@MainActor, which provides sufficient isolation guarantees for Swift 6 concurrency.
84-95: Extension signature matches protocol definition.The default implementation correctly mirrors the updated protocol signature, maintaining consistency.
firefox-ios/Client/Utils/MainThreadThrottler.swift (1)
9-10: Protocol signature update is correct.Removing
@Sendablewhile retaining@MainActoris appropriate for Swift 6 compatibility.firefox-ios/firefox-ios-tests/Tests/ClientTests/Frontend/Homepage/Mock/MockThrottler.swift (1)
13-18: Mock signature correctly updated to match protocol.The
MockThrottlerimplementation aligns with the updatedMainThreadThrottlerProtocolsignature.BrowserKit/Tests/WebEngineTests/Mock/MockWKEngineWebView.swift (1)
136-146: Mock signature correctly updated to match protocol.The
completionHandlerparameter type is now consistent with theWKEngineWebViewprotocol definition.firefox-ios/Client/TabManagement/Tab.swift (2)
857-860: Signature update is correct.The
@Sendableremoval fromgetSessionCookiescompletion is appropriate since theTabclass is marked@MainActorand the completion closure retains@MainActorisolation.
1209-1217: Override signature correctly updated for Swift 6.The
#if compiler(>=6)conditional compilation ensures the override matches the updatedWKWebViewAPI signature in Swift 6, while the#elsebranch handles older compilers with the unavailability annotation.firefox-ios/Client/Frontend/Browser/MainMenuActionHelper.swift (3)
125-126: Signature update is correct.The
completionparameter correctly retains@MainActorisolation while removing the redundant@Sendableconstraint within this@MainActorclass.
166-188: Signature update is correct.The
dataLoadingCompletionparameter update is appropriate. The completion is invoked viagroup.notify(queue: .main), ensuring main thread execution consistent with@MainActor.
543-551: Local closure type update is correct.The
actionclosure type correctly removes@Sendablewhile maintaining@MainActorisolation, consistent with the broader refactoring pattern.firefox-ios/Client/Frontend/AuthenticationManager/AppAuthenticator.swift (2)
19-26: LGTM - Protocol signatures correctly updated.The removal of
@Sendablefrom the@MainActorcompletion handlers is appropriate. Since these closures are isolated toMainActor, the@Sendableconstraint was redundant and potentially conflicting under Swift 6's stricter concurrency model.
28-49: LGTM - Implementation matches protocol.The
AppAuthenticatorimplementation correctly mirrors the updated protocol signatures. The completion handlers are properly dispatched viaDispatchQueue.main.async, ensuring main-thread execution aligns with the@MainActorannotation.firefox-ios/firefox-ios-tests/Tests/ClientTests/Mocks/MockAppAuthenticator.swift (2)
14-18: LGTM - Mock signature aligns with protocol.The mock correctly implements the updated
AppAuthenticationProtocolsignature without@Sendable.
24-34: LGTM - Authentication mock updated consistently.The
authenticateWithDeviceOwnerAuthenticationsignature matches the protocol, andensureMainThreadproperly ensures main-thread execution for the@MainActorclosure.firefox-ios/Client/Frontend/Browser/BrowserViewController/WebEngineIntegration/BrowserWebUIDelegate.swift (2)
52-64: LGTM - WKUIDelegate completion handlers updated.The
@Sendableremoval from@MainActorcompletion handlers is consistent with the PR's Swift 6 compatibility goal. The@preconcurrency import WebKit(line 5) handles any bridging concerns with WebKit's delegate expectations.
86-116: LGTM - Context menu and media capture handlers updated.Both
contextMenuConfigurationForElementandrequestMediaCapturePermissionForcompletion handlers correctly remove@Sendablewhile retaining@MainActorisolation.firefox-ios/Client/Frontend/Browser/BrowserViewController/Extensions/BrowserViewController+WebViewDelegates.swift (7)
76-92: LGTM - JavaScript alert handler updated.The
spamCallbackparameter correctly removes@Sendablewhile keeping@MainActor.
94-140: LGTM - JavaScript panel handlers updated consistently.All three JavaScript panel methods (
runJavaScriptAlertPanelWithMessage,runJavaScriptConfirmPanelWithMessage,runJavaScriptTextInputPanelWithPrompt) have completion handlers correctly updated to remove@Sendable.
153-196: LGTM - Context menu and media capture delegates updated.The completion/decision handlers for
contextMenuConfigurationForElementandrequestMediaCapturePermissionForare correctly updated.
313-319: LGTM - Action callback signature updated.The
addTabclosure parameter correctly removes@Sendablewhile maintaining@MainActorisolation.
926-940: LGTM - Download action closure updated.The
downloadActionclosure correctly removes@Sendablewhile keeping@MainActor.
1052-1098: LGTM - Authentication challenge handler updated.The
completionHandlerfordidReceive challengecorrectly removes@Sendable.
1234-1255: LGTM - External alert completion updated.The
showExternalAlertcompletion handler correctly removes@Sendable.BrowserKit/Sources/Common/Utilities/DispatchQueueInterface.swift (2)
13-13: LGTM - Protocol signature updated.The
ensureMainThreadmethod correctly removes@Sendablefrom the@MainActorclosure parameter.
38-48: LGTM - Default implementation updated.The extension's
ensureMainThreadimplementation correctly mirrors the protocol change, removing@Sendablewhile preserving the main-thread dispatch logic.BrowserKit/Sources/Common/Utilities/DispatchQueueHelper.swift (2)
10-20: LGTM - Non-genericensureMainThreadupdated.The
@Sendableremoval aligns with theDispatchQueueInterfaceprotocol and the broader PR pattern.
22-32: This is not a breaking API change—this function is newly added, not modified.The generic
ensureMainThread<T>function is new to this file. Git history confirms this entire file was just created. There are no existing callers in the codebase capturing or using the return value of this generic version; all ~200+ existing usages in the codebase call the void-returning overload. Since no code currently depends on this function, the optional return type (T?) cannot break any existing callers.The function design is semantically correct—returning
T?is appropriate when work is dispatched asynchronously and no value can be synchronously returned.Likely an incorrect or invalid review comment.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| func throttle(completion: @escaping @MainActor () -> Void) { | ||
| lastExecutionTime = Date() | ||
| guard threshold <= 0 || lastExecutionTime.timeIntervalSinceNow < -threshold else { return } | ||
| DispatchQueue.main.async(execute: completion) | ||
| } |
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.
Critical bug: Throttle logic is broken and will never execute the completion.
The execution time is updated before checking the guard condition. Since lastExecutionTime is set to Date() on line 26, lastExecutionTime.timeIntervalSinceNow will be approximately 0. The condition < -threshold (where threshold defaults to 0.35) will never be true, so the completion closure will never be dispatched.
This appears to be a regression introduced alongside the @Sendable removal. The guard should evaluate before updating lastExecutionTime.
🐛 Proposed fix
func throttle(completion: `@escaping` `@MainActor` () -> Void) {
- lastExecutionTime = Date()
guard threshold <= 0 || lastExecutionTime.timeIntervalSinceNow < -threshold else { return }
+ lastExecutionTime = Date()
DispatchQueue.main.async(execute: completion)
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| func throttle(completion: @escaping @MainActor () -> Void) { | |
| lastExecutionTime = Date() | |
| guard threshold <= 0 || lastExecutionTime.timeIntervalSinceNow < -threshold else { return } | |
| DispatchQueue.main.async(execute: completion) | |
| } | |
| func throttle(completion: `@escaping` `@MainActor` () -> Void) { | |
| guard threshold <= 0 || lastExecutionTime.timeIntervalSinceNow < -threshold else { return } | |
| lastExecutionTime = Date() | |
| DispatchQueue.main.async(execute: completion) | |
| } |
🤖 Prompt for AI Agents
In `@firefox-ios/Client/Utils/MainThreadThrottler.swift` around lines 25 - 29, In
throttle(completion:) the guard must run before updating lastExecutionTime so
the elapsed-time check uses the previous timestamp; move the assignment to
lastExecutionTime to after the guard (or compute now first and compare against
the existing lastExecutionTime) and only update lastExecutionTime when you
actually allow execution, then DispatchQueue.main.async(execute: completion) as
before; reference symbols: throttle(completion:), lastExecutionTime, threshold,
and DispatchQueue.main.async.
Benchmark PR from qodo-benchmark#208
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.