diff --git a/.github/release.yml b/.github/release.yml index a61a8c478..14fa2fcb0 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -52,17 +52,17 @@ # # `dependencies` used to be the first category, and its pull requests are # almost all bot noise, from pyup and Dependabot. Moving it down is a -# judgement call, not a data requirement: nothing in the overlaps above forces its position -# relative to anything except `release` and `ci`, both of which already rank -# ahead of it regardless of where it sits. The case for moving it here: a -# future pull request that mixes a real change with a `dependencies` label -# (say, a fix prompted by a dependency bump) surfaces under that real category -# instead of being swallowed by bot noise -- which is also, concretely, what -# keeps #22 ("New distribution [0.13.3.post2]", ci+dependencies+release) filed -# under Release rather than Dependencies. The case for leaving it first, as -# before: it keeps a high-volume, low-interest category out of the way -# of everything else on a first read. This file takes the former; flip its -# position in the list below if that judgement is wrong. +# judgement call, not a data requirement: nothing in the overlaps above forces +# its position relative to anything except `release` and `ci`, both of which +# already rank ahead of it regardless of where it sits. The case for moving it +# here: a future pull request that mixes a real change with a `dependencies` +# label (say, a fix prompted by a dependency bump) surfaces under that real +# category instead of being swallowed by bot noise -- which is also, +# concretely, what keeps #22 ("New distribution [0.13.3.post2]", +# ci+dependencies+release) filed under Release rather than Dependencies. The +# case for leaving it first, as before: it keeps a high-volume, low-interest +# category out of the way of everything else on a first read. This file takes +# the former; flip its position in the list below if that judgement is wrong. # # `*` catches whatever matches none of the categories above -- nothing in the # sample, since every pull request in it carried a type label, but it stays diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index ea0f9749e..091c3f73b 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -129,12 +129,12 @@ concurrency: # pair does not. A cancelled ``tag`` would otherwise send ``conda`` into its # check that ``conda-+0`` names this run's commit, for a tag ``tag`` # never pushed, trading a clean skip for a failed step. ``version_check`` is held -# to a stricter bar still: all of them require ``needs.version_check.result == -# 'success'`` with no ``|| 'skipped'``, since it produces the evidence the gates -# below read, and a skipped or cancelled ``version_check`` leaves them nothing -# to decide on. Either spelling bypasses the default ``success()`` GitHub -# Actions would otherwise prepend to an ``if:`` that does not itself call a -# status-check function. +# to a stricter bar still: ``tag``, ``pypi`` and ``conda`` all require +# ``needs.version_check.result == 'success'`` with no ``|| 'skipped'``, +# since it produces the evidence the gates below read, and a skipped or +# cancelled ``version_check`` leaves them nothing to decide on. Either +# spelling bypasses the default ``success()`` GitHub Actions would otherwise +# prepend to an ``if:`` that does not itself call a status-check function. # # See ``release_status`` at the bottom of this file for the other half: a job # that runs whenever the run itself was not cancelled (``if: !cancelled()``, @@ -148,9 +148,9 @@ concurrency: # that the gate -- a ~20-minute full-suite run -- is spent only when something # is going to be published. Every successful Vendor Update triggers this # workflow, and most of them leave ``__version__`` alone, so the gate used to -# run on commits Unit Tests had already passed only for every job below to -# skip (eight times on 2026-10-05 alone). ``unit-tests`` runs when the ref -# is a ``v*`` tag or *any* of the evidence outputs is not ``'true'``, +# run on commits Unit Tests had already passed only for every publisher +# below to skip (eight times on 2026-10-05 alone). ``unit-tests`` runs when +# the ref is a ``v*`` tag or *any* of the evidence outputs is not ``'true'``, # which covers every case in which ``github``, ``tag``, ``pypi`` or ``conda`` # could run: each of them runs only on a ``v*`` ref or on its own evidence # reading ``'false'``. ``!= 'true'`` rather than ``== 'false'`` is deliberate -- diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index f14d0de4a..0cf7a2b0e 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -682,8 +682,8 @@ jobs: # green and never red for the wrong reason. If it # ever starts building, the cell fails loudly. # - # One job per engine loops over every interpreter, each in a fresh venv, - # rather than one job per cell (every Python times every engine): the queue, + # One job per engine loops over its interpreters, each in a fresh venv, + # rather than one job per cell (one engine on one Python): the queue, # not the runners, is the bottleneck, and a job per cell would pay checkout, # setup and apt for a minute of work. One job per *engine* rather than per Python # because the engine is what varies the environment: the apt packages diff --git a/examples/generators/legacy.py b/examples/generators/legacy.py index d6bf684ac..dfc089c21 100644 --- a/examples/generators/legacy.py +++ b/examples/generators/legacy.py @@ -18,8 +18,8 @@ delivered out of order, with one of them retransmitted; the IPv6 request body is spread over three segments delivered in order. The IPv4 connection closes with a FIN from each end, the IPv6 one with a FIN from the server - and an abortive RST from the client, so the capture covers each event - that makes :mod:`pcapkit` submit a datagram. + and an abortive RST from the client, so the capture covers a + FIN-completed stream and an RST-aborted one. ``http6.cap`` Read by ``examples/legacy_smoke/test_analyse.py``, which pretty-prints the @@ -49,10 +49,16 @@ :class:`pcapkit.foundation.reassembly.tcp.TCP` decide what a capture has to look like for a datagram to come out of it at all: -1. A buffer is keyed by the connection's four-tuple *including direction*, and - :meth:`~pcapkit.foundation.reassembly.tcp.TCP.submit` runs only when that - direction sends FIN or RST. A half-closed connection yields one datagram, - not two, so both ends of every connection here close. +1. A buffer is keyed by the connection's four-tuple *including direction*, so + each direction is a datagram of its own. + :meth:`~pcapkit.foundation.reassembly.tcp.TCP.submit` runs on that + direction's RST; once its FIN has been seen and every octet below the FIN + has arrived; when a SYN, or a segment farther than ``__window__`` from the + buffer, opens a new one on the same four-tuple; on a timeout, if one is + set; and, for whatever is still buffered, when the capture ends. So a + half-closed connection still yields a datagram per direction. Both ends of + every connection here close anyway, so that each datagram is submitted by + its own FIN or RST rather than by that final flush. 2. Inside a buffer, fragments are keyed by the segment's *acknowledgement* number, so consecutive data segments merge only while the peer sends no data of its own. Both fixtures therefore keep each direction of each @@ -706,8 +712,8 @@ def _write_test(dest: 'pathlib.Path') -> 'pathlib.Path': capture.add(page.data(False, parts[2], offset=offset), delay=0.198365) capture.add(page.ack()) - # and the connection closes from both ends, which is what makes pcapkit - # submit the two datagrams + # and the connection closes from both ends, so each direction's FIN + # submits its datagram capture.add(page.fin(False)) capture.add(page.ack()) capture.add(page.fin()) @@ -755,7 +761,7 @@ def _write_http6(dest: 'pathlib.Path') -> 'pathlib.Path': conditional request the browser makes for the stylesheet the page references, which the server answers ``304 Not Modified`` -- a response with a header block, no body and no ``Content-Length``. Both connections - close from both ends, so every datagram is submitted. + close from both ends, so each datagram is submitted by its own FIN. Args: dest: Destination directory. diff --git a/util/run_unittest_leg.py b/util/run_unittest_leg.py index e0147e9ed..265b60595 100644 --- a/util/run_unittest_leg.py +++ b/util/run_unittest_leg.py @@ -53,9 +53,9 @@ its timings, on different bases (a local serial run, and CI before and after it was sharded), are tabulated in that workflow's own comment rather than restated here. At the other end sit -:mod:`tests.dumpkit` and :mod:`tests.interface`, small legs with no clean -ordering between them by test count or by wall time (~39s and ~37s). Neither -small leg is :mod:`tests.const` (~268s), which is larger by both measures. +:mod:`tests.dumpkit` and :mod:`tests.interface`, small legs within a few +seconds of each other in wall time (~39s and ~37s). Neither small leg is +:mod:`tests.const` (~268s), which is larger by test count as well. Peak RSS was measured for the three cheapest legs only, via :func:`resource.getrusage` on ``RUSAGE_CHILDREN`` in this venv: