Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
9e9827f chore: upgrade axum to 0.7
The largest changes are caused by the associated upgrade of hyper to
1.0, including the removal of
axum::Server
(replaced byaxum::serve
)and http body utilities (replaced by
http-body-util
). These changeswere purely mechanical.
A more subtle change is the requirement from
http
1.0 for requestextensions to be
Clone
. TheLazy
transaction wrapper is notClone
,so it has been wrapped in an
Arc
, withArc::get_mut
being used toobtain the necessary mutability. This feels like it might be buggy,
since other middleware could potentially clone and store request
extensions, without otherwise interfering with the transaction (meaning
the
Tx
extractor should still work). This needs subsequentinvestigation before release.
84a49ae fix: fix buggy behaviour when cloning request extensions
Our naive update for [email protected] / [email protected] led to buggy behaviour whereby
the
Tx
extractor would always fail withOverlappingExtractors
ifthere were any outstanding clones of the request extensions (see the new
test). Since request extensions now must all implement
Clone
, it'spossible that some middleware might wish to keep a clone of all request
extensions (e.g. for request inspection/tracing/debugging), rendering
Tx
unusable with those middleware.To fix it, we simplify the synchronisation by implementing
Clone
forSlot
and creating newExtension<DB>
andLazyTransaction<DB>
typesto replace
TxSlot<DB>
andLazy<DB>
.Slot<T>
is a wrapper around anArc<Mutex<Option<T>>>
, and as such itcan trivially implement
Clone
(there was some "pit of success"considerations with the previous API intended to enforce proper usage,
but that is unnecesarily limiting given the underlying
Mutex
).The
Extension<DB>
holds aSlot
containing aLazyTransaction<DB>
.Extension<DB>
is trivially clonable sinceSlot
itself is. TheLazyTransaction<DB>
then implements a simple "lazily acquiredtransaction" protocol, making use of normal rust ownership and borrowing
rules to manage the transaction (i.e. it has no internal
synchronisation).
This makes the overall synchronisation picture much simpler: the
middleware future and all clones of the request extension hold a
reference to the same
Slot
. TheTx
extractor obtains its copy of therequest extension and attempts to
lease
the innerLazyTransaction
,failing with
OverlappingExtractors
if the lease is already taken (thisis the only public invocation of
lease
, and so overlapping extractorscan be the only* cause of an absent transaction). If the lease is
successful, the extractor can acquire a transaction (if there's not one
already) and package it up for request handlers to then interact with.
Tx
extractor bycommitting explicitly, but this considered to create an endless
"overlap" in the current semantics.
The main caveat of this approach seems to be that the
Tx
extractor nolonger has type-level knowledge that it can access a
Transaction
- theTransaction
can only be accessed by matching on theLazyTransaction
state. This doesn't affect the API, but it could make bumping into a
panic more likely, or there may be performance implications (though
these would likely be dwarfed by the I/O involved in interacting with a
database).
1cec0ae refactor: ditch
slot
It turns out the
parking_lot
arc_lock
future does the main thing wewant from
Slot
, giving us'static
lock guards that unlock the valueon drop. The only missing functionality is the "stealing" we need to
obtain ownership in order to commit the transaction. Rather than
implementing this via
Option
, we add an additional state toLazyTransaction
and handle it there.Ultimately this removes a lot of code, and makes the synchronisation
mechanism even less exotic.