queue teardown behind an in-flight procedure - #61
Merged
Conversation
This was referenced Jul 26, 2026
next-nf
force-pushed
the
async-gate-51-m3
branch
from
July 27, 2026 11:44
0e92e90 to
033dae2
Compare
next-nf
force-pushed
the
async-gate-step5-teardown
branch
from
July 27, 2026 11:44
584827d to
efaa53b
Compare
next-nf
force-pushed
the
async-gate-51-m3
branch
from
July 27, 2026 12:16
033dae2 to
4fb8c8e
Compare
next-nf
force-pushed
the
async-gate-step5-teardown
branch
from
July 27, 2026 12:16
efaa53b to
7d593ff
Compare
next-nf
force-pushed
the
async-gate-51-m3
branch
from
July 27, 2026 12:23
4fb8c8e to
8657782
Compare
next-nf
force-pushed
the
async-gate-step5-teardown
branch
from
July 27, 2026 12:23
7d593ff to
e117e67
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Closes the coarse gate's last real coverage gap: the teardown surface.
A parked
async_mprocedure holds a pre-await snapshot ofpcf/aaa_session/pcc/pfcp, and its terminal write-back restores that snapshot intoData. Any teardownthat ran in between is silently reverted — the same corruption class commit
259d441fixed for the fire-and-forget Gx
{'$reply'}path. Architecture §4 is explicit: "DeleteSession is an ordinary session-level procedure that queues, marks the context
terminating, and on running reconciles/tears down whatever completed."
The GTP-borne Delete Session Request was already gated (it arrives as
cast {handle_message, …}). The internal and administrative entry points were not:{call, {delete_context, _}},{call, delete_context},cast {delete_context, _}andthe
context_idletimeout all ran immediately.What's here
Four gate clauses alongside the existing five, each guarded on
map_size(P) =/= 0and the session beingconnected/connecting. The session guardmatters twice over: the existing
#{session := shutdown}clause must keep answering{ok, ok}immediately, and a context torn down by a failure keeps its registry entry —so without the guard the cast and timeout clauses would postpone in
shutdownand neverre-fire.
Testing
teardown_queues_behind_procedureparks aupdate_creditsprocedure with the UPF held,then drives
delete_contextfrom a spawned process. It asserts no Delete Bearer Requestreaches the control socket while parked, then that the queued teardown completes once the
gate frees and the call returns
{ok, request_accepted}. Verified red first: before theclauses it fails on exactly that assertion, with a
delete_bearer_requestarriving insteadof the expected timeout.
pgw_SUITE136/136; withggsn_SUITEandsaegw_s11_SUITE, 236 total, 0 failures.Two things I scoped out after investigating, rather than shipping unjustified code
Draining the registry on failure teardowns (UPF
DOWN,peer_down,terminate_context) — planned, then dropped.close_context/4removespfcpfromDataand the context deregisters, so nothing afterwards consults the registry andasync_pending_sizecannot even be read ({noproc, …}). There is no demonstrable wedgeand no test that could discriminate the change. The session-state guard above handles the
one real consequence — my own new clauses postponing in
shutdown.The
259d441fire-and-forget race test that async error callbacks routing through handle_ctx_error/4 don't drain async_pending -> coarse gate can wedge #51 asked for — filed as test the fire-and-forget Gx {'$reply'} race the coarse gate serializes (259d441) #60 instead.{'$reply', Promise, Handler, Result, Config}is sent only fromsmf_aaa_diameter_srv.erl:130, the real Diameter path, andpgw_SUITEruns thesynchronous
smf_aaa_staticmock, which mints no Promise. The alternatives were standingup a real Diameter peer in a suite that deliberately uses the mock, or injecting a
synthetic
{'$reply'}matching nothing — which would test the postpone clause but not thewrite-back race it protects against.
Also settled by reading, no code needed: per-resource gate concurrency. Architecture §2
rejects it outright — "There is no per-bearer parallelism … a single per-context
procedure gate + FIFO queue, not scoped locks." The remaining step-5 item is the RAR
inline-RAA refinement (architecture §3), which is a design-conformance gap rather than a
spec violation: per TS 29.213 §8.2 the
DIAMETER_PENDING_TRANSACTIONrules bind only whenboth peers advertised the PendingTransaction feature, and next-nf neither implements nor
negotiates it.
Stacked on #59. Merge bottom-up: #45 → #46 → #48 → #56 → #57 → #58 → #59 → this.