Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: simplify synchronisation to handle cloned request extensions
This follows on from the upgrade to axum 0.7 / hyper 1.0 which introduced the requirement for request extensions to implement `Clone`. The previous implementation exibited undesirable behaviour if some middleware (that ran after `axum_sqlx_tx::Layer`) held on to a clone of the request extensions - specifically an `OverlappingExtractors` error would then be thrown by any attempt to extract `Tx`. Note that in this circumstance it's not actually possible for the "inspecting" middleware to obtain the transaction since it cannot name the type of the extension (`crate::extension::Extension`, previously `crate::tx::Lazy`) in order to interact with it. The fix involved simplifying the `Slot` synchronisation primitive and the usage of it in the extension. We previously had a "chained" `Slot` setup (e.g. a `Slot` containing another `Slot`) in order to share the lazy transaction between the middleware future and the request extension - the `Slot` remained in the middleware future stack while the `Lease` was passed to the request extension. This was problematic because `Lease` doesn't implement `Clone`, and it mustn't since the whole idea is to synchronise access to a `Transaction` which itself cannot be cloned. Now `Slot`s can be cloned, so the same `Slot` can be held in the middleware future's stack and in the request extension. Moreover, an arbitrary number of copies of the `Slot` can be held without preventing another `Slot` from leasing (so long as there's no other lease) - just like `Mutex`. This still achieves the outcome we want because the only public interface to the `Slot` is via `Tx::from_request_parts`, thus a conflict can only occur due to overlapping use of the extractor.
- Loading branch information