Skip to content

Commit d7e84c2

Browse files
committed
Replace the networking figure; rewrite both code chunks' prose
User-flagged: /examples/networking attached protocol-layers (an HTTP/TCP/IP stack figure) to an example whose code uses socket.socketpair() to demonstrate the str ↔ bytes boundary. The figure had no relationship to the lesson, and the two code chunks on the page shared generic prose instead of explaining what each chunk actually shows. Figure New socket-byte-boundary figure (src/marginalia.py): str "ping" → encode → bytes b'ping' → [dashed socket pipe, labelled "socket"] → bytes b'ping' → decode → str "ping". The figure depicts what the example's code does in one row: the encode/decode at each end of the socket carrying bytes. Canvas 364×46 → renders at 627 CSS px on desktop, comfortably under the 640 banner ceiling. Removed protocol_layers (now orphan after re-attaching). The orphan-figure contract catches it automatically. Cell prose (src/example_sources/networking.md) Unsupported chunk now explains what its three-line code does — socketpair returns two endpoints, sendall encodes, recv reads bytes — with the Dynamic Workers caveat moved to a closing parenthetical instead of leading the prose. Cell chunk now explains what the full version adds over the unsupported fragment: try/finally for cleanup, second print that decodes the received bytes back to a str. TDD: the new figure tripped Contract 2 (collision) on the first draft — the "SOCKET" tag overlapped a bytes box. Moved the tag above the dashed pipe instead of below. The attachment also tripped Contract 6 (anchor coverage) — I attached to cell-1 but the example has only one runnable :::cell. Fixed to cell-0. Both caught in CI, fixed before merge. 57 tests pass; SCORES commentary updated.
1 parent 604cca3 commit d7e84c2

5 files changed

Lines changed: 22 additions & 15 deletions

File tree

public/prototyping/marginalia-gestalt.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -687,8 +687,8 @@ <h3>Threads and Processes</h3>
687687
<div class="card">
688688
<p class="eyebrow">Standard Library · 105</p>
689689
<h3>Networking</h3>
690-
<svg viewBox="-14 -14 228 128" width="365" height="205" xmlns="http://www.w3.org/2000/svg"><rect x="0" y="0" width="200" height="20" fill="none" stroke="#521000" stroke-width="1.0"/><text x="100.0" y="14.0" font-family="'JetBrains Mono', 'IBM Plex Mono', Menlo, monospace" font-size="10" fill="#521000" text-anchor="middle">application · HTTP</text><rect x="0" y="22" width="200" height="20" fill="none" stroke="#521000" stroke-width="1.0"/><text x="100.0" y="36.0" font-family="'JetBrains Mono', 'IBM Plex Mono', Menlo, monospace" font-size="10" fill="#521000" text-anchor="middle">transport · TCP</text><rect x="0" y="44" width="200" height="20" fill="none" stroke="#521000" stroke-width="1.0"/><text x="100.0" y="58.0" font-family="'JetBrains Mono', 'IBM Plex Mono', Menlo, monospace" font-size="10" fill="#521000" text-anchor="middle">network · IP</text><rect x="0" y="66" width="200" height="20" fill="none" stroke="#521000" stroke-width="1.0"/><text x="100.0" y="80.0" font-family="'JetBrains Mono', 'IBM Plex Mono', Menlo, monospace" font-size="10" fill="#521000" text-anchor="middle">link</text></svg>
691-
<p class="score score-high">9.0 · HTTP / TCP / IP / link stack</p>
690+
<svg viewBox="-14 -14 392 74" width="627" height="118" xmlns="http://www.w3.org/2000/svg"><rect x="0" y="18" width="64" height="22" fill="rgba(82, 16, 0, 0.05)" stroke="#521000" stroke-width="1.0"/><text x="4" y="13" font-family="-apple-system, 'Source Sans Pro', sans-serif" font-size="8" fill="rgba(82, 16, 0, 0.7)" text-anchor="start" letter-spacing="0.5">STR</text><text x="32.0" y="33.0" font-family="'JetBrains Mono', 'IBM Plex Mono', Menlo, monospace" font-size="10" fill="#521000" text-anchor="middle">"ping"</text><line x1="64" y1="29" x2="89.0" y2="29.0" stroke="#521000" stroke-width="1.0"/><polygon points="96,29 89.0,31.8 89.0,26.2" fill="#521000"/><text x="80" y="23" font-family="-apple-system, 'Source Sans Pro', sans-serif" font-size="9" fill="rgba(82, 16, 0, 0.7)" text-anchor="middle">encode</text><rect x="98" y="18" width="70" height="22" fill="rgba(82, 16, 0, 0.05)" stroke="#521000" stroke-width="1.0"/><text x="102" y="13" font-family="-apple-system, 'Source Sans Pro', sans-serif" font-size="8" fill="rgba(82, 16, 0, 0.7)" text-anchor="start" letter-spacing="0.5">BYTES</text><text x="133.0" y="33.0" font-family="'JetBrains Mono', 'IBM Plex Mono', Menlo, monospace" font-size="10" fill="#521000" text-anchor="middle">b'ping'</text><line x1="168" y1="29" x2="192" y2="29" stroke="#521000" stroke-width="0.6" stroke-dasharray="2 2"/><text x="180" y="8" font-family="-apple-system, 'Source Sans Pro', sans-serif" font-size="8" fill="rgba(82, 16, 0, 0.7)" text-anchor="middle" letter-spacing="0.5">SOCKET</text><rect x="194" y="18" width="70" height="22" fill="rgba(82, 16, 0, 0.05)" stroke="#521000" stroke-width="1.0"/><text x="198" y="13" font-family="-apple-system, 'Source Sans Pro', sans-serif" font-size="8" fill="rgba(82, 16, 0, 0.7)" text-anchor="start" letter-spacing="0.5">BYTES</text><text x="229.0" y="33.0" font-family="'JetBrains Mono', 'IBM Plex Mono', Menlo, monospace" font-size="10" fill="#521000" text-anchor="middle">b'ping'</text><line x1="264" y1="29" x2="289.0" y2="29.0" stroke="#521000" stroke-width="1.0"/><polygon points="296,29 289.0,31.8 289.0,26.2" fill="#521000"/><text x="280" y="23" font-family="-apple-system, 'Source Sans Pro', sans-serif" font-size="9" fill="rgba(82, 16, 0, 0.7)" text-anchor="middle">decode</text><rect x="298" y="18" width="64" height="22" fill="rgba(82, 16, 0, 0.05)" stroke="#521000" stroke-width="1.0"/><text x="302" y="13" font-family="-apple-system, 'Source Sans Pro', sans-serif" font-size="8" fill="rgba(82, 16, 0, 0.7)" text-anchor="start" letter-spacing="0.5">STR</text><text x="330.0" y="33.0" font-family="'JetBrains Mono', 'IBM Plex Mono', Menlo, monospace" font-size="10" fill="#521000" text-anchor="middle">"ping"</text></svg>
691+
<p class="score score-high">9.0 · text ↔ bytes across the socket boundary</p>
692692
</div>
693693
<div class="card">
694694
<p class="eyebrow">Standard Library · 106</p>

public/prototyping/production-figures-gestalt.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

src/asset_manifest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# Generated by scripts/fingerprint_assets.py. Do not edit by hand.
22
ASSET_PATHS = {'SITE_CSS': '/site.f9a6740c684b.css', 'SYNTAX_JS': '/syntax-highlight.3b6c7f730d46.js', 'EDITOR_JS': '/editor.dd81f5171b14.js'}
3-
HTML_CACHE_VERSION = '6403f9817e89'
3+
HTML_CACHE_VERSION = '4a27d9ac9a3e'

src/example_sources/networking.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ finally:
3131
:::
3232

3333
:::unsupported
34-
Dynamic Workers do not provide arbitrary low-level sockets, and this app disables Dynamic Worker outbound access.
34+
`socketpair()` returns two connected endpoints. `sendall` writes encoded bytes into one end, and `recv` reads up to 16 bytes off the other. The byte boundary is the whole point: `"ping".encode("utf-8")` produces `b'ping'`, which is what the socket actually moves. (This fragment runs in standard Python only — Dynamic Workers don't expose arbitrary sockets and this app disables Worker outbound access.)
3535

3636
```python
3737
left, right = socket.socketpair()
@@ -41,7 +41,7 @@ data = right.recv(16)
4141
:::
4242

4343
:::cell
44-
Sockets exchange bytes. Encoding and decoding make the boundary between Python text and network data visible.
44+
The complete version adds two things: a `try`/`finally` so both endpoints close even if `recv` or the surrounding work raises, and a second `print` that `decode`s the received bytes back into a Python `str` for display. The first `print` shows the raw bytes `b'ping'`; the second shows the decoded text `ping`.
4545

4646
```python
4747
import socket

src/marginalia.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,11 +1055,18 @@ def aaa_pattern(c: Canvas) -> None:
10551055
c.cell(110, i * 24, body, w=140, h=22)
10561056

10571057

1058-
def protocol_layers(c: Canvas) -> None:
1059-
"""Networking · each layer in the stack hides the next; HTTP rests on TCP on IP on the link."""
1060-
layers = ["application · HTTP", "transport · TCP", "network · IP", "link"]
1061-
for i, name in enumerate(layers):
1062-
c.cell(0, i * 22, name, w=200, h=20)
1058+
def socket_byte_boundary(c: Canvas) -> None:
1059+
"""Networking · sockets carry bytes; encode marks the python → wire boundary, decode the wire → python boundary."""
1060+
c.object_box(0, 18, "str", '"ping"', w=64, h=22)
1061+
c.closed_arrow(64, 29, 96, 29, emphasis=False)
1062+
c.label(80, 23, "encode", anchor="middle")
1063+
c.object_box(98, 18, "bytes", "b'ping'", w=70, h=22, soft=True)
1064+
c.dashed(168, 29, 192, 29)
1065+
c.tag(180, 8, "socket", anchor="middle")
1066+
c.object_box(194, 18, "bytes", "b'ping'", w=70, h=22, soft=True)
1067+
c.closed_arrow(264, 29, 296, 29, emphasis=False)
1068+
c.label(280, 23, "decode", anchor="middle")
1069+
c.object_box(298, 18, "str", '"ping"', w=64, h=22)
10631070

10641071

10651072
def gil_lanes(c: Canvas) -> None:
@@ -1347,7 +1354,7 @@ def lazy_stream(c: Canvas) -> None:
13471354
"subprocess-spawn": (subprocess_spawn, 324, 60),
13481355
"logging-levels": (logging_levels, 164, 124),
13491356
"aaa-pattern": (aaa_pattern, 250, 80),
1350-
"protocol-layers": (protocol_layers, 200, 100),
1357+
"socket-byte-boundary": (socket_byte_boundary, 364, 46),
13511358
"gil-lanes": (gil_lanes, 300, 100),
13521359
"cast-escape": (cast_escape, 184, 56),
13531360
"newtype-phantom": (newtype_phantom, 96, 92),
@@ -1802,8 +1809,8 @@ def lazy_stream(c: Canvas) -> None:
18021809
"arrange-act-assert: set up the state, perform the behavior under test, compare the result to expectations.",
18031810
)],
18041811
"networking": [(
1805-
"cell-0", "protocol-layers",
1806-
"Network protocols stack: HTTP rests on TCP, which rests on IP, which rests on the link layer.",
1812+
"cell-0", "socket-byte-boundary",
1813+
"Text crosses the socket as bytes — `encode` marks the python → wire boundary, `decode` brings the bytes back to a Python `str`.",
18071814
)],
18081815
"threads-and-processes": [(
18091816
"cell-0", "gil-lanes",
@@ -2119,7 +2126,7 @@ def render_for_section(section_title: str) -> str:
21192126
"subprocesses": (9.0, "spawn → child → captured output"),
21202127
"logging": (9.0, "five thresholded levels"),
21212128
"testing": (9.0, "arrange-act-assert three-row pattern"),
2122-
"networking": (9.0, "HTTP / TCP / IP / link stack"),
2129+
"networking": (9.0, "text ↔ bytes across the socket boundary"),
21232130
"casts-and-any": (9.0, "Any → cast(T, x) → T, runtime unchanged"),
21242131
"newtype": (9.0, "same runtime, distinct static identity"),
21252132
"paramspec": (9.0, "P preserved through decorator"),

0 commit comments

Comments
 (0)