| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
Replace #file with #fileID (#4003) ### Issue Link :link: Resolves #4002 ### Goals :soccer: This PR replaces the one use of `#file` with `#fileID`, as the language hasn't fully migrated. Swift through Xcode seems to already use the `#file = #fileID` behavior, so this may only change for non-Apple platforms or when compiled with certain flags. ### Testing Details :mag: None, only passed through a fatal error. | 6 个月前 | |
Stabilize CI And Fix Bugs (#4030) ### Goals :soccer: Alamofire has long had many tests which pass 100% of the time locally, but occasionally fail in CI. This PR fixes those tests, and the underlying issues uncovered, through a combination of manual and tool-assisted analysis over many, many CI runs. ### Implementation Details :construction: Some of these fixes are actually adoptions of existing testing patterns but most address timing issues in Alamofire itself. - `AuthenticationInterceptor` has been refactored to track more state and ensure requests are only retried once. - 🔥 There is a bit of a behavior change here. `AuthenticationInterceptor` will allow more requests to fail and wait for retry rather than holding them at the request adaptation step. This ensures they fully rerun their request pipeline to pick up the latest adaptations. Unfortunately, it wasn't possible to do this when held for adaptation. - `Request.suspend()` and `Request.cancel()` could be ineffective if called at narrow points within the `Request` lifecycle. These updates are now more atomic. - `Request.cancel()` (and overrides) could call `Request.finish()` when the request was already completed, leading to duplicate lifecycle events. - `Request.resume()` could create extra `URLSessionTask`s if called at narrow points in the lifecycle. - Similarly, rapid `Request.resume()` to `Request.suspend()` and back calls could lead a request performing multiple times. - `Request` could create multiple tasks during narrow points in its lifetime. - `Session.deinit` is now thread-safe. Unfortunately this required yet another lock, but should ensure it operates safely from any thread. - `Session.deinit` was internally racy, which could lead to duplicate `Request.finish()` calls. It now allows the `Session` to shut down while it finishes the requests separately in the `SessionDelegate`. - `Request` task updates were moved to the `Request` itself, to ensure they're always atomic relative to external state updates like `cancel()` or `resume()`. - `Request.onHTTPResponse`'s `.cancel` disposition didn't call the full `Request.cancel()`, which could lead to different behavior, like `EventMonitor` callbacks. - Most `unowned self` usage has been removed. - `DataStreamRequest`'s `outputStream` could have `write` called after `close()`, this is now properly checked. - `MIMEType` checking would improperly match invalid types like `text` to `text/plain`, this has been addressed and this parsing and matching are now specifically tested. - `DownloadRequest` now properly checks `!isCancelled` before attempting retry. - `DataTask` and `DownloadTask` didn't properly handle `cancel()` before creating their task. `Task.isCancelled` is now checked immediately after creation to ensure cancellation. Many test implementations have been updated: - All tests now use a unique `stored(Session())`, where possible. This ensures they never share state. - More data is used for upload and download requests tracking progress, but it may not be enough. Tests are so fast, and progress reporting isn't guaranteed, so the test may never be 100% reliable. - Separate stream setup from `async let`. Since `async let` can make sync work async, which means the stream setup races with the request itself. - Fixed the `URLProtocol` tests with correct event ordering. - Various tests were changed structurally to eliminate races. ### Testing Details :mag: Many tests updated and added. | 5 个月前 | |
Stabilize CI And Fix Bugs (#4030) ### Goals :soccer: Alamofire has long had many tests which pass 100% of the time locally, but occasionally fail in CI. This PR fixes those tests, and the underlying issues uncovered, through a combination of manual and tool-assisted analysis over many, many CI runs. ### Implementation Details :construction: Some of these fixes are actually adoptions of existing testing patterns but most address timing issues in Alamofire itself. - `AuthenticationInterceptor` has been refactored to track more state and ensure requests are only retried once. - 🔥 There is a bit of a behavior change here. `AuthenticationInterceptor` will allow more requests to fail and wait for retry rather than holding them at the request adaptation step. This ensures they fully rerun their request pipeline to pick up the latest adaptations. Unfortunately, it wasn't possible to do this when held for adaptation. - `Request.suspend()` and `Request.cancel()` could be ineffective if called at narrow points within the `Request` lifecycle. These updates are now more atomic. - `Request.cancel()` (and overrides) could call `Request.finish()` when the request was already completed, leading to duplicate lifecycle events. - `Request.resume()` could create extra `URLSessionTask`s if called at narrow points in the lifecycle. - Similarly, rapid `Request.resume()` to `Request.suspend()` and back calls could lead a request performing multiple times. - `Request` could create multiple tasks during narrow points in its lifetime. - `Session.deinit` is now thread-safe. Unfortunately this required yet another lock, but should ensure it operates safely from any thread. - `Session.deinit` was internally racy, which could lead to duplicate `Request.finish()` calls. It now allows the `Session` to shut down while it finishes the requests separately in the `SessionDelegate`. - `Request` task updates were moved to the `Request` itself, to ensure they're always atomic relative to external state updates like `cancel()` or `resume()`. - `Request.onHTTPResponse`'s `.cancel` disposition didn't call the full `Request.cancel()`, which could lead to different behavior, like `EventMonitor` callbacks. - Most `unowned self` usage has been removed. - `DataStreamRequest`'s `outputStream` could have `write` called after `close()`, this is now properly checked. - `MIMEType` checking would improperly match invalid types like `text` to `text/plain`, this has been addressed and this parsing and matching are now specifically tested. - `DownloadRequest` now properly checks `!isCancelled` before attempting retry. - `DataTask` and `DownloadTask` didn't properly handle `cancel()` before creating their task. `Task.isCancelled` is now checked immediately after creation to ensure cancellation. Many test implementations have been updated: - All tests now use a unique `stored(Session())`, where possible. This ensures they never share state. - More data is used for upload and download requests tracking progress, but it may not be enough. Tests are so fast, and progress reporting isn't guaranteed, so the test may never be 100% reliable. - Separate stream setup from `async let`. Since `async let` can make sync work async, which means the stream setup races with the request itself. - Fixed the `URLProtocol` tests with correct event ordering. - Various tests were changed structurally to eliminate races. ### Testing Details :mag: Many tests updated and added. | 5 个月前 | |
Stabilize CI And Fix Bugs (#4030) ### Goals :soccer: Alamofire has long had many tests which pass 100% of the time locally, but occasionally fail in CI. This PR fixes those tests, and the underlying issues uncovered, through a combination of manual and tool-assisted analysis over many, many CI runs. ### Implementation Details :construction: Some of these fixes are actually adoptions of existing testing patterns but most address timing issues in Alamofire itself. - `AuthenticationInterceptor` has been refactored to track more state and ensure requests are only retried once. - 🔥 There is a bit of a behavior change here. `AuthenticationInterceptor` will allow more requests to fail and wait for retry rather than holding them at the request adaptation step. This ensures they fully rerun their request pipeline to pick up the latest adaptations. Unfortunately, it wasn't possible to do this when held for adaptation. - `Request.suspend()` and `Request.cancel()` could be ineffective if called at narrow points within the `Request` lifecycle. These updates are now more atomic. - `Request.cancel()` (and overrides) could call `Request.finish()` when the request was already completed, leading to duplicate lifecycle events. - `Request.resume()` could create extra `URLSessionTask`s if called at narrow points in the lifecycle. - Similarly, rapid `Request.resume()` to `Request.suspend()` and back calls could lead a request performing multiple times. - `Request` could create multiple tasks during narrow points in its lifetime. - `Session.deinit` is now thread-safe. Unfortunately this required yet another lock, but should ensure it operates safely from any thread. - `Session.deinit` was internally racy, which could lead to duplicate `Request.finish()` calls. It now allows the `Session` to shut down while it finishes the requests separately in the `SessionDelegate`. - `Request` task updates were moved to the `Request` itself, to ensure they're always atomic relative to external state updates like `cancel()` or `resume()`. - `Request.onHTTPResponse`'s `.cancel` disposition didn't call the full `Request.cancel()`, which could lead to different behavior, like `EventMonitor` callbacks. - Most `unowned self` usage has been removed. - `DataStreamRequest`'s `outputStream` could have `write` called after `close()`, this is now properly checked. - `MIMEType` checking would improperly match invalid types like `text` to `text/plain`, this has been addressed and this parsing and matching are now specifically tested. - `DownloadRequest` now properly checks `!isCancelled` before attempting retry. - `DataTask` and `DownloadTask` didn't properly handle `cancel()` before creating their task. `Task.isCancelled` is now checked immediately after creation to ensure cancellation. Many test implementations have been updated: - All tests now use a unique `stored(Session())`, where possible. This ensures they never share state. - More data is used for upload and download requests tracking progress, but it may not be enough. Tests are so fast, and progress reporting isn't guaranteed, so the test may never be 100% reliable. - Separate stream setup from `async let`. Since `async let` can make sync work async, which means the stream setup races with the request itself. - Fixed the `URLProtocol` tests with correct event ordering. - Various tests were changed structurally to eliminate races. ### Testing Details :mag: Many tests updated and added. | 5 个月前 | |
Deprecate `NetworkReachabilityManager` (#3947) ### Issue Link :link: Fixes #3943 ### Goals :soccer: Apple's `SCNetworkReachability` types were deprecated in iOS 17.4 related OS versions. This PR deprecates `NetworkReachabilityManager` in favor of `NWPathMonitor` from Network.framework, which has been the better solution for many years now. This PR also updates various infrastructure bits, and deletes the `.swiftpm` directory to prevent Xcode from generating schemes when integrating the package. ### Implementation Details :construction: Class deprecated. ### Testing Details :mag: Tests deprecated. | 11 个月前 | |
Make `HTTPMethod` Sendable (#3848) ### Goals :soccer: Just like the https://github.com/Alamofire/Alamofire/pull/3816 but for `HTTPMethod`. | 2 年前 | |
Allow Empty EventMonitors And Try To Fix `CompositeEventMonitor` Thread-Safety (#3894) ### Issue Link :link: #3635, #3667 ### Goals :soccer: This PR attempts to fix unreproducible `CompositeEventMonitor` crashes in two ways: 1. Passing `[]` to the `Session` inits now creates a `CompositeEventMonitor` that's properly empty rather than always including an `AlamofireNotifications` monitor. This should allow anyone seeing this crash to empty out the monitors to see if the crash is resolved. **Technically this is a breaking change** as anyone passing `[]` currently has notification support. This should be rare, and this fix is important enough to justify breaking that non-obvious usage. 2. The stored monitors in the `CompositeEventMonitor` are now protected and accessed through a lock, so should be made safer. Of course, I could never figure out how any access there could be unsafe since it should always be accessed on the serial internal queue, so we'll see if that helps anything. ### Implementation Details :construction: `Session` init updated, lock added. ### Testing Details :mag: No tests added, test suite passes. | 2 年前 | |
Update CI for GHA Limitations (#3973) ### Goals :soccer: This PR updates CI for all Xcode versions and GHA's limited sim availability. | 11 个月前 | |
Swift 6 Native Builds (#3880) ### Goals :soccer: This PR tracks the implementation of full concurrency checking when building in Swift 6 mode. It's unknown whether all of these changes will be fully backward compatible. ### Implementation Details :construction: This PR largely consists of `Sendable` annotations, with a few logic changes to fix actual safety issues. ### Testing Details :mag: Tests updated with needed annotations, but mutation warnings need a larger overall refactor. | 1 年前 | |
More Atomic Locking (#3984) ### Issue Link :link: Attempts to fix #3978 ### Goals :soccer: This PR is a speculative attempt to fix the continuation resumption crash seen in #3978. However, I was unable to reproduce that issues, even with more complicated test cases and over 50 million test iterations. So this PR makes a few parts of `Request`'s state management more atomic, especially around response serializer handling. It also removes `@dynamicMemberLookup` from `Protected`, which should encourage more atomic usage. ### Implementation Details :construction: This PR attempts to unify what were separate lock access in the same flow into single accesses that accomplish the same thing. Behaviorally should be the same but may prevent any intermediate accesses to state that might cause this issue. ### Testing Details :mag: No new test scenarios, as no reproduction could be found. | 11 个月前 | |
Stabilize CI And Fix Bugs (#4030) ### Goals :soccer: Alamofire has long had many tests which pass 100% of the time locally, but occasionally fail in CI. This PR fixes those tests, and the underlying issues uncovered, through a combination of manual and tool-assisted analysis over many, many CI runs. ### Implementation Details :construction: Some of these fixes are actually adoptions of existing testing patterns but most address timing issues in Alamofire itself. - `AuthenticationInterceptor` has been refactored to track more state and ensure requests are only retried once. - 🔥 There is a bit of a behavior change here. `AuthenticationInterceptor` will allow more requests to fail and wait for retry rather than holding them at the request adaptation step. This ensures they fully rerun their request pipeline to pick up the latest adaptations. Unfortunately, it wasn't possible to do this when held for adaptation. - `Request.suspend()` and `Request.cancel()` could be ineffective if called at narrow points within the `Request` lifecycle. These updates are now more atomic. - `Request.cancel()` (and overrides) could call `Request.finish()` when the request was already completed, leading to duplicate lifecycle events. - `Request.resume()` could create extra `URLSessionTask`s if called at narrow points in the lifecycle. - Similarly, rapid `Request.resume()` to `Request.suspend()` and back calls could lead a request performing multiple times. - `Request` could create multiple tasks during narrow points in its lifetime. - `Session.deinit` is now thread-safe. Unfortunately this required yet another lock, but should ensure it operates safely from any thread. - `Session.deinit` was internally racy, which could lead to duplicate `Request.finish()` calls. It now allows the `Session` to shut down while it finishes the requests separately in the `SessionDelegate`. - `Request` task updates were moved to the `Request` itself, to ensure they're always atomic relative to external state updates like `cancel()` or `resume()`. - `Request.onHTTPResponse`'s `.cancel` disposition didn't call the full `Request.cancel()`, which could lead to different behavior, like `EventMonitor` callbacks. - Most `unowned self` usage has been removed. - `DataStreamRequest`'s `outputStream` could have `write` called after `close()`, this is now properly checked. - `MIMEType` checking would improperly match invalid types like `text` to `text/plain`, this has been addressed and this parsing and matching are now specifically tested. - `DownloadRequest` now properly checks `!isCancelled` before attempting retry. - `DataTask` and `DownloadTask` didn't properly handle `cancel()` before creating their task. `Task.isCancelled` is now checked immediately after creation to ensure cancellation. Many test implementations have been updated: - All tests now use a unique `stored(Session())`, where possible. This ensures they never share state. - More data is used for upload and download requests tracking progress, but it may not be enough. Tests are so fast, and progress reporting isn't guaranteed, so the test may never be 100% reliable. - Separate stream setup from `async let`. Since `async let` can make sync work async, which means the stream setup races with the request itself. - Fixed the `URLProtocol` tests with correct event ordering. - Various tests were changed structurally to eliminate races. ### Testing Details :mag: Many tests updated and added. | 5 个月前 | |
Update Infrastructure (#4017) ### Goals :soccer: This PR updates actions and dependencies. This PR also fixes two issues: - A rare duplicate metrics crash seen when using `usesClassicLoadingMode = false`. - An extremely rare logic race between the creation of a `StreamOf` and the start of iteration, where values could be lost. | 6 个月前 | |
Swift 6 Native Builds (#3880) ### Goals :soccer: This PR tracks the implementation of full concurrency checking when building in Swift 6 mode. It's unknown whether all of these changes will be fully backward compatible. ### Implementation Details :construction: This PR largely consists of `Sendable` annotations, with a few logic changes to fix actual safety issues. ### Testing Details :mag: Tests updated with needed annotations, but mutation warnings need a larger overall refactor. | 1 年前 | |
Stabilize CI And Fix Bugs (#4030) ### Goals :soccer: Alamofire has long had many tests which pass 100% of the time locally, but occasionally fail in CI. This PR fixes those tests, and the underlying issues uncovered, through a combination of manual and tool-assisted analysis over many, many CI runs. ### Implementation Details :construction: Some of these fixes are actually adoptions of existing testing patterns but most address timing issues in Alamofire itself. - `AuthenticationInterceptor` has been refactored to track more state and ensure requests are only retried once. - 🔥 There is a bit of a behavior change here. `AuthenticationInterceptor` will allow more requests to fail and wait for retry rather than holding them at the request adaptation step. This ensures they fully rerun their request pipeline to pick up the latest adaptations. Unfortunately, it wasn't possible to do this when held for adaptation. - `Request.suspend()` and `Request.cancel()` could be ineffective if called at narrow points within the `Request` lifecycle. These updates are now more atomic. - `Request.cancel()` (and overrides) could call `Request.finish()` when the request was already completed, leading to duplicate lifecycle events. - `Request.resume()` could create extra `URLSessionTask`s if called at narrow points in the lifecycle. - Similarly, rapid `Request.resume()` to `Request.suspend()` and back calls could lead a request performing multiple times. - `Request` could create multiple tasks during narrow points in its lifetime. - `Session.deinit` is now thread-safe. Unfortunately this required yet another lock, but should ensure it operates safely from any thread. - `Session.deinit` was internally racy, which could lead to duplicate `Request.finish()` calls. It now allows the `Session` to shut down while it finishes the requests separately in the `SessionDelegate`. - `Request` task updates were moved to the `Request` itself, to ensure they're always atomic relative to external state updates like `cancel()` or `resume()`. - `Request.onHTTPResponse`'s `.cancel` disposition didn't call the full `Request.cancel()`, which could lead to different behavior, like `EventMonitor` callbacks. - Most `unowned self` usage has been removed. - `DataStreamRequest`'s `outputStream` could have `write` called after `close()`, this is now properly checked. - `MIMEType` checking would improperly match invalid types like `text` to `text/plain`, this has been addressed and this parsing and matching are now specifically tested. - `DownloadRequest` now properly checks `!isCancelled` before attempting retry. - `DataTask` and `DownloadTask` didn't properly handle `cancel()` before creating their task. `Task.isCancelled` is now checked immediately after creation to ensure cancellation. Many test implementations have been updated: - All tests now use a unique `stored(Session())`, where possible. This ensures they never share state. - More data is used for upload and download requests tracking progress, but it may not be enough. Tests are so fast, and progress reporting isn't guaranteed, so the test may never be 100% reliable. - Separate stream setup from `async let`. Since `async let` can make sync work async, which means the stream setup races with the request itself. - Fixed the `URLProtocol` tests with correct event ordering. - Various tests were changed structurally to eliminate races. ### Testing Details :mag: Many tests updated and added. | 5 个月前 | |
Stabilize CI And Fix Bugs (#4030) ### Goals :soccer: Alamofire has long had many tests which pass 100% of the time locally, but occasionally fail in CI. This PR fixes those tests, and the underlying issues uncovered, through a combination of manual and tool-assisted analysis over many, many CI runs. ### Implementation Details :construction: Some of these fixes are actually adoptions of existing testing patterns but most address timing issues in Alamofire itself. - `AuthenticationInterceptor` has been refactored to track more state and ensure requests are only retried once. - 🔥 There is a bit of a behavior change here. `AuthenticationInterceptor` will allow more requests to fail and wait for retry rather than holding them at the request adaptation step. This ensures they fully rerun their request pipeline to pick up the latest adaptations. Unfortunately, it wasn't possible to do this when held for adaptation. - `Request.suspend()` and `Request.cancel()` could be ineffective if called at narrow points within the `Request` lifecycle. These updates are now more atomic. - `Request.cancel()` (and overrides) could call `Request.finish()` when the request was already completed, leading to duplicate lifecycle events. - `Request.resume()` could create extra `URLSessionTask`s if called at narrow points in the lifecycle. - Similarly, rapid `Request.resume()` to `Request.suspend()` and back calls could lead a request performing multiple times. - `Request` could create multiple tasks during narrow points in its lifetime. - `Session.deinit` is now thread-safe. Unfortunately this required yet another lock, but should ensure it operates safely from any thread. - `Session.deinit` was internally racy, which could lead to duplicate `Request.finish()` calls. It now allows the `Session` to shut down while it finishes the requests separately in the `SessionDelegate`. - `Request` task updates were moved to the `Request` itself, to ensure they're always atomic relative to external state updates like `cancel()` or `resume()`. - `Request.onHTTPResponse`'s `.cancel` disposition didn't call the full `Request.cancel()`, which could lead to different behavior, like `EventMonitor` callbacks. - Most `unowned self` usage has been removed. - `DataStreamRequest`'s `outputStream` could have `write` called after `close()`, this is now properly checked. - `MIMEType` checking would improperly match invalid types like `text` to `text/plain`, this has been addressed and this parsing and matching are now specifically tested. - `DownloadRequest` now properly checks `!isCancelled` before attempting retry. - `DataTask` and `DownloadTask` didn't properly handle `cancel()` before creating their task. `Task.isCancelled` is now checked immediately after creation to ensure cancellation. Many test implementations have been updated: - All tests now use a unique `stored(Session())`, where possible. This ensures they never share state. - More data is used for upload and download requests tracking progress, but it may not be enough. Tests are so fast, and progress reporting isn't guaranteed, so the test may never be 100% reliable. - Separate stream setup from `async let`. Since `async let` can make sync work async, which means the stream setup races with the request itself. - Fixed the `URLProtocol` tests with correct event ordering. - Various tests were changed structurally to eliminate races. ### Testing Details :mag: Many tests updated and added. | 5 个月前 | |
Swift 6 Native Builds (#3880) ### Goals :soccer: This PR tracks the implementation of full concurrency checking when building in Swift 6 mode. It's unknown whether all of these changes will be fully backward compatible. ### Implementation Details :construction: This PR largely consists of `Sendable` annotations, with a few logic changes to fix actual safety issues. ### Testing Details :mag: Tests updated with needed annotations, but mutation warnings need a larger overall refactor. | 1 年前 | |
Lazy Requests, per-Request Features (#3996) ### Issue Link :link: Closes #3992, other feature requests. ### Goals :soccer: This PR includes four major new features: 1. By default, all `Request` set up is now fully lazy and does not start until the instance is resumed, whether automatically or manually. Virtually all users should be unimpacted by this change, aside from seeing fewer race conditions. For those that do see issues, the previous behavior can be restored by passing `requestSetup: .eager` to the `Session.init`. 2. Speaking of `resume()`, automatic resume is now controllable on a per-`Request` basis using the `shouldAutomaticallyResumeParameter`. By default this is `nil` an obeys the `Session` setting. 3. You can now add a `RequestAdapter`, `RequestRetrier`, or `RequestInterceptor` after `Request.init`, like any other chained Alamofire API. This is what necessitated the lazy start change, as adapters added in this manner are racy with eager `Request`s and may miss the appropriate lifetime events. 4. In addition to the interceptors, you can now add a per-`Request` `EventMonitor` that is composed after the `Session`'s event monitor. ```swift // shouldAutomaticallyResume defaults to nil, obeying the Session's setting, which // defaults to true. let request = <session>.request(<urlRequest>, shouldAutomaticallyResume: true) .adapt(using: <adapter>) .retry(using: <retrier>) .interceptor(<interceptor>) .eventMonitor(<monitor>) // request is inert until resumed or a response handler (when automatic resume is enabled) // is added. let response = await request.serializingDecoding(<Type>.self).response ``` ### Implementation Details :construction: Actual changes were rather minimal for the impact these features have. 1. Simple stored interceptor and monitor are now stored in the mutable state and new instance methods have been added to provide those values. 2. Internally, the previous `perform` method has been split between eager and lazy variants, and a new `RequestDelegate` method has been added to start the request when needed (upon resume). 3. Interceptors and EventMonitors are now composed `Session`-first, to guarantee that `Request`s can override `Session` interceptor behavior. ### Testing Details :mag: Tests against very specific `Request` lifetime timing were updated to use an `eager` `Session`, to replicate the previous behavior. However, these tests are almost always inherently racy, which made them flaky in CI, so this sort of breaking behavioral change is more of a bug fix. Users could never really rely on these event orderings before, as `Request` start and the events themselves would race. Additional tests added to cover the new APIs, and some tests have been converted to Swift Testing for performance and ergonomics. Additionally, the test target deployment targets have been bumped again, as the testing frameworks technically only deploy back to macOS 14, etc. | 9 个月前 | |
Lazy Requests, per-Request Features (#3996) ### Issue Link :link: Closes #3992, other feature requests. ### Goals :soccer: This PR includes four major new features: 1. By default, all `Request` set up is now fully lazy and does not start until the instance is resumed, whether automatically or manually. Virtually all users should be unimpacted by this change, aside from seeing fewer race conditions. For those that do see issues, the previous behavior can be restored by passing `requestSetup: .eager` to the `Session.init`. 2. Speaking of `resume()`, automatic resume is now controllable on a per-`Request` basis using the `shouldAutomaticallyResumeParameter`. By default this is `nil` an obeys the `Session` setting. 3. You can now add a `RequestAdapter`, `RequestRetrier`, or `RequestInterceptor` after `Request.init`, like any other chained Alamofire API. This is what necessitated the lazy start change, as adapters added in this manner are racy with eager `Request`s and may miss the appropriate lifetime events. 4. In addition to the interceptors, you can now add a per-`Request` `EventMonitor` that is composed after the `Session`'s event monitor. ```swift // shouldAutomaticallyResume defaults to nil, obeying the Session's setting, which // defaults to true. let request = <session>.request(<urlRequest>, shouldAutomaticallyResume: true) .adapt(using: <adapter>) .retry(using: <retrier>) .interceptor(<interceptor>) .eventMonitor(<monitor>) // request is inert until resumed or a response handler (when automatic resume is enabled) // is added. let response = await request.serializingDecoding(<Type>.self).response ``` ### Implementation Details :construction: Actual changes were rather minimal for the impact these features have. 1. Simple stored interceptor and monitor are now stored in the mutable state and new instance methods have been added to provide those values. 2. Internally, the previous `perform` method has been split between eager and lazy variants, and a new `RequestDelegate` method has been added to start the request when needed (upon resume). 3. Interceptors and EventMonitors are now composed `Session`-first, to guarantee that `Request`s can override `Session` interceptor behavior. ### Testing Details :mag: Tests against very specific `Request` lifetime timing were updated to use an `eager` `Session`, to replicate the previous behavior. However, these tests are almost always inherently racy, which made them flaky in CI, so this sort of breaking behavioral change is more of a bug fix. Users could never really rely on these event orderings before, as `Request` start and the events themselves would race. Additional tests added to cover the new APIs, and some tests have been converted to Swift Testing for performance and ergonomics. Additionally, the test target deployment targets have been bumped again, as the testing frameworks technically only deploy back to macOS 14, etc. | 9 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 6 个月前 | ||
| 5 个月前 | ||
| 5 个月前 | ||
| 5 个月前 | ||
| 11 个月前 | ||
| 2 年前 | ||
| 2 年前 | ||
| 11 个月前 | ||
| 1 年前 | ||
| 11 个月前 | ||
| 5 个月前 | ||
| 6 个月前 | ||
| 1 年前 | ||
| 5 个月前 | ||
| 5 个月前 | ||
| 1 年前 | ||
| 9 个月前 | ||
| 9 个月前 |