Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions .github/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,12 @@ concurrency:
# pair does not. A cancelled ``tag`` would otherwise send ``conda`` into its
# check that ``conda-<version>+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()``,
Expand All @@ -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 --
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 15 additions & 9 deletions examples/generators/legacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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.
Expand Down
6 changes: 3 additions & 3 deletions util/run_unittest_leg.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Loading