Skip to content

queue teardown behind an in-flight procedure - #61

Merged
next-nf merged 2 commits into
mainfrom
async-gate-step5-teardown
Jul 27, 2026
Merged

queue teardown behind an in-flight procedure#61
next-nf merged 2 commits into
mainfrom
async-gate-step5-teardown

Conversation

@next-nf

@next-nf next-nf commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Closes the coarse gate's last real coverage gap: the teardown surface.

A parked async_m procedure holds a pre-await snapshot of pcf/aaa_session/pcc/
pfcp, and its terminal write-back restores that snapshot into Data. Any teardown
that ran in between is silently reverted — the same corruption class commit 259d441
fixed for the fire-and-forget Gx {'$reply'} path. Architecture §4 is explicit: "Delete
Session 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, _} and
the context_idle timeout all ran immediately.

What's here

Four gate clauses alongside the existing five, each guarded on
map_size(P) =/= 0 and the session being connected/connecting. The session guard
matters 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 shutdown and never
re-fire.

Testing

teardown_queues_behind_procedure parks a update_credits procedure with the UPF held,
then drives delete_context from a spawned process. It asserts no Delete Bearer Request
reaches 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 the
clauses it fails on exactly that assertion, with a delete_bearer_request arriving instead
of the expected timeout.

pgw_SUITE 136/136; with ggsn_SUITE and saegw_s11_SUITE, 236 total, 0 failures.

Two things I scoped out after investigating, rather than shipping unjustified code

  1. Draining the registry on failure teardowns (UPF DOWN, peer_down,
    terminate_context) — planned, then dropped. close_context/4 removes pfcp from
    Data and the context deregisters, so nothing afterwards consults the registry and
    async_pending_size cannot even be read ({noproc, …}). There is no demonstrable wedge
    and no test that could discriminate the change. The session-state guard above handles the
    one real consequence — my own new clauses postponing in shutdown.

  2. The 259d441 fire-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 from
    smf_aaa_diameter_srv.erl:130, the real Diameter path, and pgw_SUITE runs the
    synchronous smf_aaa_static mock, which mints no Promise. The alternatives were standing
    up 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 the
    write-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_TRANSACTION rules bind only when
both 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.

@next-nf
next-nf force-pushed the async-gate-51-m3 branch from 4fb8c8e to 8657782 Compare July 27, 2026 12:23
@next-nf
next-nf force-pushed the async-gate-step5-teardown branch from 7d593ff to e117e67 Compare July 27, 2026 12:23
Base automatically changed from async-gate-51-m3 to main July 27, 2026 12:29
@next-nf
next-nf merged commit 7697313 into main Jul 27, 2026
@next-nf
next-nf deleted the async-gate-step5-teardown branch July 27, 2026 12:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant