| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
Refactor Project Structure, Break Request Types Out Into Separate Files (#3819) ### Goals :soccer: Alamofire's project structure has grown from its original single-file origin into many files on disk. Unfortunately, as the project has grown, the `Request.swift` file has grown rather gigantic, topping 2600 lines after the recent addition of `WebSocketRequest`. This PR breaks up `Request.swift` into separate files for each request type. It also moves all the previous serialization extensions from `ResponseSerialization.swift` to their associated type's files. This PR also restructures some of the project's layout on disk to make some Xcode groups proper folders. This PR also creates the `AFInfo` namespace and moves the previously internal `version` value into it to make it public. This PR also adds primary associated types to the serialization protocols. | 2 年前 | |
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. | 4 个月前 | |
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 年前 | |
Add FreeBSD compilation support (#4029) ### Issue Link :link: Fix compile on FreeBSD ### Goals :soccer: Fix compile on FreeBSD ### Testing Details :mag: Ran swift build on FreeBSD --------- Co-authored-by: Al Hoang <3811822-hoanga@users.noreply.gitlab.com> | 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. | 4 个月前 | |
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. | 8 个月前 | |
Add FreeBSD compilation support (#4029) ### Issue Link :link: Fix compile on FreeBSD ### Goals :soccer: Fix compile on FreeBSD ### Testing Details :mag: Ran swift build on FreeBSD --------- Co-authored-by: Al Hoang <3811822-hoanga@users.noreply.gitlab.com> | 5 个月前 | |
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. | 10 个月前 | |
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. | 10 个月前 | |
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. | 4 个月前 | |
Add `@Sendable` to `AdaptHandler` and `RetryHandler` Closure Parameters (#3906) ### Issue Link :link: Fixes #3905 ### Goals :soccer: This PR adds `@Sendable` to the closure types used by the interceptors. This PR also normalizes the order of closure attributes to `@escaping @Sendable`. ### Testing Details :mag: No tests updated. | 1 年前 | |
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 年前 | |
Add `@Sendable` to `AdaptHandler` and `RetryHandler` Closure Parameters (#3906) ### Issue Link :link: Fixes #3905 ### Goals :soccer: This PR adds `@Sendable` to the closure types used by the interceptors. This PR also normalizes the order of closure attributes to `@escaping @Sendable`. ### Testing Details :mag: No tests updated. | 1 年前 | |
Make `Empty` `Hashable` (#3985) ### Goals :soccer: This PR adds `Hashable` (and therefore `Equatable`) to Alamofire's `Empty` type, so it can meet more generic constraints for responses. ### Implementation Details :construction: Synthesized conformance made public. ### Testing Details :mag: Updated some usage tests to check equals. | 10 个月前 | |
Add @Sendable to RetryPolicy.retry's completion (#3994) ### Goals :soccer: <!-- List the high-level objectives of this pull request. --> <!-- Include any relevant context. --> Adding on to #3906, this PR adds `@Sendable` to the completion handler of RetryPolicy's retry function | 8 个月前 | |
Prepare 5.10 (#3900) ### Goals :soccer: This PR prepares the 5.10 release. | 1 年前 | |
Prevent Duplicate Serializer Completion Calls (#3999) ### Issue Link :link: Fixes #3978 ### Goals :soccer: This PR fixes the possible duplicate completion handler calls that cause #3978. Due to multiple paths into `processNextResponseSerializer()` there was a logical race where the same response serializer could be completed multiple times when cancelled, leading to a concurrency runtime crash due to resuming a continuation more than once. ### Implementation Details :construction: Additional state was added to track whether a `Request` had currently enqueued a serializer which is checked upon entering `processNextResponseSerializer()`, allowing it to return early if a serializer is in flight. This ensures that no matter how many times `processNextResponseSerializer()` is called, only one attempt will enqueue a particular serializer and, potentially, its completion. ### Testing Details :mag: Additional test added which could locally reproduce the issue. | 7 个月前 | |
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. | 4 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 2 年前 | ||
| 4 个月前 | ||
| 1 年前 | ||
| 5 个月前 | ||
| 4 个月前 | ||
| 8 个月前 | ||
| 5 个月前 | ||
| 10 个月前 | ||
| 10 个月前 | ||
| 4 个月前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 10 个月前 | ||
| 8 个月前 | ||
| 1 年前 | ||
| 7 个月前 | ||
| 4 个月前 |