gecko-web-runtime-client 1.2.0__tar.gz → 1.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/PKG-INFO +28 -16
  2. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/README.md +27 -15
  3. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/installer.py +3 -3
  4. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/network/client.py +5 -5
  5. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime_client.egg-info/PKG-INFO +28 -16
  6. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/pyproject.toml +1 -1
  7. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/__init__.py +0 -0
  8. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/__main__.py +0 -0
  9. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/_leases.py +0 -0
  10. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/api/__init__.py +0 -0
  11. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/api/context.py +0 -0
  12. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/api/page.py +0 -0
  13. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/api/pool.py +0 -0
  14. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/api/runtime.py +0 -0
  15. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/data_plane.py +0 -0
  16. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/diagnostics/__init__.py +0 -0
  17. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/diagnostics/gc_cc.py +0 -0
  18. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/diagnostics/logging.py +0 -0
  19. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/diagnostics/memory.py +0 -0
  20. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/diagnostics/metrics.py +0 -0
  21. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/diagnostics/resources.py +0 -0
  22. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/http.py +0 -0
  23. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/iocp_pipe.py +0 -0
  24. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/models/__init__.py +0 -0
  25. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/models/navigation.py +0 -0
  26. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/network/__init__.py +0 -0
  27. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/network/_urls.py +0 -0
  28. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/network/exceptions.py +0 -0
  29. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/network/models.py +0 -0
  30. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/network/transport.py +0 -0
  31. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/pipe.py +0 -0
  32. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/session.py +0 -0
  33. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/workflows/__init__.py +0 -0
  34. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/workflows/turnstile.py +0 -0
  35. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime/workflows/wechat.py +0 -0
  36. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime_client.egg-info/SOURCES.txt +0 -0
  37. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime_client.egg-info/dependency_links.txt +0 -0
  38. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime_client.egg-info/requires.txt +0 -0
  39. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/gecko_web_runtime_client.egg-info/top_level.txt +0 -0
  40. {gecko_web_runtime_client-1.2.0 → gecko_web_runtime_client-1.3.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gecko-web-runtime-client
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: Thin Python client for the Firefox-derived WPR Gecko Worker protocol
5
5
  Author: WPR project
6
6
  License: MPL-2.0-compatible client; see the runtime bundle notices
@@ -11,6 +11,12 @@ Requires-Dist: loguru>=0.7.2; extra == "diagnostics"
11
11
 
12
12
  # Python client
13
13
 
14
+ Version `1.3.0` defaults to one Worker, 20 Channels,
15
+ `ipc_backend="iocp"` and `release_mode="piggyback"`. Published version 1.2.0
16
+ still defaults to one Channel, threaded IPC and immediate release. Runtime
17
+ 155.0.5 is required for the new defaults. Existing 1.2.0 installations keep
18
+ their behavior until explicitly upgraded.
19
+
14
20
  The client provides a standard-library core plus an optional Loguru-backed
15
21
  diagnostics layer. From this directory:
16
22
 
@@ -66,16 +72,17 @@ helpers), `network/transport.py` (the versioned Worker boundary),
66
72
 
67
73
  `timeout` accepts seconds, `Timeout(total=seconds, pool=seconds)`, or `None`.
68
74
  `total` covers queueing plus the active request; `pool` can bound waiting for
69
- an available Worker slot. By default `max_workers=1`, so `asyncio.gather()` calls
70
- on one client queue behind one Worker. Set `max_workers=N` to let the same
71
- client instance dispatch up to N requests at once:
75
+ an available request slot. The 1.3.0 default is one Worker with 20
76
+ concurrent Channels. `asyncio.gather()` submits the work; the client limits
77
+ active requests to `max_workers * max_channels_per_worker`. No arguments are
78
+ needed to discover the installed runtime and enable the default transport:
72
79
 
73
80
  ```python
74
81
  import asyncio
75
82
  from gecko_web_runtime import AsyncWprHttpClient
76
83
 
77
84
  async def main():
78
- async with AsyncWprHttpClient(max_workers=4, timeout=30) as client:
85
+ async with AsyncWprHttpClient() as client:
79
86
  responses = await asyncio.gather(
80
87
  *(client.get(f"https://example.com/api/{i}") for i in range(8))
81
88
  )
@@ -87,8 +94,8 @@ async def main():
87
94
  asyncio.run(main())
88
95
  ```
89
96
 
90
- This is a bounded Gecko Worker pool, not an HTTP socket-connection limit: the
91
- current named-pipe RPC accepts one in-flight request per Worker. Each extra
97
+ Channels bound in-flight requests, not HTTP sockets or Python threads. Set
98
+ `max_channels_per_worker` to change the single-Worker limit. Each extra
92
99
  Worker is a separate Firefox process/profile and therefore has its own Gecko
93
100
  CookieService state; multi-Worker cookie continuity is not shared or ordered.
94
101
  Keep the default `max_workers=1` when requests depend on a single browser cookie
@@ -96,12 +103,14 @@ jar or when minimizing memory is more important than parallel throughput. The
96
103
  pool grows lazily up to the configured cap and reuses Workers after requests.
97
104
  For latency-sensitive bursts, call `await client.warmup(url)` immediately after
98
105
  entering the client and before sending application requests. It starts the
99
- remaining Workers and makes one full GET per Worker to the supplied URL; the
106
+ remaining Workers and makes one full GET per Channel slot to the supplied URL; the
100
107
  responses are read and released while the Worker connections stay open. This
101
108
  is real traffic, so use a safe, idempotent endpoint. Cookies set by that
102
- endpoint remain isolated in each Worker profile.
103
- An active client-side timeout or cancellation stops that Worker because the
104
- current protocol has no per-request cancellation; the next call replaces it.
109
+ endpoint remain isolated in each Worker profile. With the new defaults a
110
+ warmup call makes 20 real GETs; entering a client by itself makes none.
111
+ Active timeout/cancellation in the default multiplexed mode cancels only its
112
+ request Channel. Explicit legacy single-Channel mode stops the Worker and
113
+ the next request replaces it.
105
114
  A queued request timeout leaves active requests and Workers untouched.
106
115
  Connect/read/write phase timeouts still need native Worker support.
107
116
 
@@ -127,8 +136,9 @@ completes. Set `WPR_RUNTIME_HOME`, `WPR_RUNTIME_DIR`, and
127
136
 
128
137
  Client 1.2.0 with runtime 155.0.5 supports `ipc_backend="iocp"` and
129
138
  `max_channels_per_worker=10` with `max_workers=1`, keeping one shared
130
- cookie/proxy session while issuing concurrent Necko requests. Defaults remain
131
- the independent-Worker threaded path. Older runtimes lack these capabilities;
139
+ cookie/proxy session while issuing concurrent Necko requests. Version 1.2.0
140
+ uses explicit opt-in; version 1.3.0 selects these features by default.
141
+ Older runtimes lack these capabilities;
132
142
  upgrade both the client and runtime before enabling multi-Channel requests.
133
143
  See [selection, protocol, and reproducible build instructions](../source/gecko-net-worker/experiments/multiplex-network/README.md).
134
144
 
@@ -151,7 +161,8 @@ exact instantaneous maxima, or a claim of equivalent physical RAM consumption.
151
161
  See [results, limitations, and reproduction commands](tests/results/http-resource-comparison-20261011.md).
152
162
  The test entry points are `tests/integration/baidu_live_ab.py` and
153
163
  `tests/integration/baidu_resource_ab.py`. They remain development tests; the
154
- release keeps opt-in concurrency and transport defaults unchanged.
164
+ measurements refer to the released 1.2.0 configuration, not a claim that
165
+ the 1.3.0 defaults have identical resource costs.
155
166
 
156
167
  ## Network IPC diagnostics and pipe A/B
157
168
 
@@ -222,7 +233,7 @@ $env:WPR_PIPE_MODE = 'persistent'
222
233
  ```
223
234
 
224
235
  ```python
225
- async with AsyncWprHttpClient(max_workers=10, release_mode="piggyback") as client:
236
+ async with AsyncWprHttpClient() as client:
226
237
  response = await client.get("http://127.0.0.1:8080/")
227
238
  body = await response.aread()
228
239
  await client.flush_releases() # Optional explicit Worker-side confirmation.
@@ -236,7 +247,8 @@ pipe occupancy can delay it. Thresholds of 32 entries or 8 MiB trigger drains;
236
247
  they are not global caps on unread response memory. Only acknowledged entries
237
248
  are removed from the pending queue. Abort stops the Worker and discards its queue.
238
249
 
239
- The default remains `release_mode="immediate"`. Old Workers are rejected during
250
+ The 1.3.0 default is `release_mode="piggyback"`; pass `"immediate"`
251
+ explicitly to release each response through a separate RPC. Old Workers are rejected during
240
252
  capability negotiation if piggyback mode is requested, before any HTTP request
241
253
  is sent. `transport_stats` covers the currently resident pool, not retired Workers.
242
254
 
@@ -1,5 +1,11 @@
1
1
  # Python client
2
2
 
3
+ Version `1.3.0` defaults to one Worker, 20 Channels,
4
+ `ipc_backend="iocp"` and `release_mode="piggyback"`. Published version 1.2.0
5
+ still defaults to one Channel, threaded IPC and immediate release. Runtime
6
+ 155.0.5 is required for the new defaults. Existing 1.2.0 installations keep
7
+ their behavior until explicitly upgraded.
8
+
3
9
  The client provides a standard-library core plus an optional Loguru-backed
4
10
  diagnostics layer. From this directory:
5
11
 
@@ -55,16 +61,17 @@ helpers), `network/transport.py` (the versioned Worker boundary),
55
61
 
56
62
  `timeout` accepts seconds, `Timeout(total=seconds, pool=seconds)`, or `None`.
57
63
  `total` covers queueing plus the active request; `pool` can bound waiting for
58
- an available Worker slot. By default `max_workers=1`, so `asyncio.gather()` calls
59
- on one client queue behind one Worker. Set `max_workers=N` to let the same
60
- client instance dispatch up to N requests at once:
64
+ an available request slot. The 1.3.0 default is one Worker with 20
65
+ concurrent Channels. `asyncio.gather()` submits the work; the client limits
66
+ active requests to `max_workers * max_channels_per_worker`. No arguments are
67
+ needed to discover the installed runtime and enable the default transport:
61
68
 
62
69
  ```python
63
70
  import asyncio
64
71
  from gecko_web_runtime import AsyncWprHttpClient
65
72
 
66
73
  async def main():
67
- async with AsyncWprHttpClient(max_workers=4, timeout=30) as client:
74
+ async with AsyncWprHttpClient() as client:
68
75
  responses = await asyncio.gather(
69
76
  *(client.get(f"https://example.com/api/{i}") for i in range(8))
70
77
  )
@@ -76,8 +83,8 @@ async def main():
76
83
  asyncio.run(main())
77
84
  ```
78
85
 
79
- This is a bounded Gecko Worker pool, not an HTTP socket-connection limit: the
80
- current named-pipe RPC accepts one in-flight request per Worker. Each extra
86
+ Channels bound in-flight requests, not HTTP sockets or Python threads. Set
87
+ `max_channels_per_worker` to change the single-Worker limit. Each extra
81
88
  Worker is a separate Firefox process/profile and therefore has its own Gecko
82
89
  CookieService state; multi-Worker cookie continuity is not shared or ordered.
83
90
  Keep the default `max_workers=1` when requests depend on a single browser cookie
@@ -85,12 +92,14 @@ jar or when minimizing memory is more important than parallel throughput. The
85
92
  pool grows lazily up to the configured cap and reuses Workers after requests.
86
93
  For latency-sensitive bursts, call `await client.warmup(url)` immediately after
87
94
  entering the client and before sending application requests. It starts the
88
- remaining Workers and makes one full GET per Worker to the supplied URL; the
95
+ remaining Workers and makes one full GET per Channel slot to the supplied URL; the
89
96
  responses are read and released while the Worker connections stay open. This
90
97
  is real traffic, so use a safe, idempotent endpoint. Cookies set by that
91
- endpoint remain isolated in each Worker profile.
92
- An active client-side timeout or cancellation stops that Worker because the
93
- current protocol has no per-request cancellation; the next call replaces it.
98
+ endpoint remain isolated in each Worker profile. With the new defaults a
99
+ warmup call makes 20 real GETs; entering a client by itself makes none.
100
+ Active timeout/cancellation in the default multiplexed mode cancels only its
101
+ request Channel. Explicit legacy single-Channel mode stops the Worker and
102
+ the next request replaces it.
94
103
  A queued request timeout leaves active requests and Workers untouched.
95
104
  Connect/read/write phase timeouts still need native Worker support.
96
105
 
@@ -116,8 +125,9 @@ completes. Set `WPR_RUNTIME_HOME`, `WPR_RUNTIME_DIR`, and
116
125
 
117
126
  Client 1.2.0 with runtime 155.0.5 supports `ipc_backend="iocp"` and
118
127
  `max_channels_per_worker=10` with `max_workers=1`, keeping one shared
119
- cookie/proxy session while issuing concurrent Necko requests. Defaults remain
120
- the independent-Worker threaded path. Older runtimes lack these capabilities;
128
+ cookie/proxy session while issuing concurrent Necko requests. Version 1.2.0
129
+ uses explicit opt-in; version 1.3.0 selects these features by default.
130
+ Older runtimes lack these capabilities;
121
131
  upgrade both the client and runtime before enabling multi-Channel requests.
122
132
  See [selection, protocol, and reproducible build instructions](../source/gecko-net-worker/experiments/multiplex-network/README.md).
123
133
 
@@ -140,7 +150,8 @@ exact instantaneous maxima, or a claim of equivalent physical RAM consumption.
140
150
  See [results, limitations, and reproduction commands](tests/results/http-resource-comparison-20261011.md).
141
151
  The test entry points are `tests/integration/baidu_live_ab.py` and
142
152
  `tests/integration/baidu_resource_ab.py`. They remain development tests; the
143
- release keeps opt-in concurrency and transport defaults unchanged.
153
+ measurements refer to the released 1.2.0 configuration, not a claim that
154
+ the 1.3.0 defaults have identical resource costs.
144
155
 
145
156
  ## Network IPC diagnostics and pipe A/B
146
157
 
@@ -211,7 +222,7 @@ $env:WPR_PIPE_MODE = 'persistent'
211
222
  ```
212
223
 
213
224
  ```python
214
- async with AsyncWprHttpClient(max_workers=10, release_mode="piggyback") as client:
225
+ async with AsyncWprHttpClient() as client:
215
226
  response = await client.get("http://127.0.0.1:8080/")
216
227
  body = await response.aread()
217
228
  await client.flush_releases() # Optional explicit Worker-side confirmation.
@@ -225,7 +236,8 @@ pipe occupancy can delay it. Thresholds of 32 entries or 8 MiB trigger drains;
225
236
  they are not global caps on unread response memory. Only acknowledged entries
226
237
  are removed from the pending queue. Abort stops the Worker and discards its queue.
227
238
 
228
- The default remains `release_mode="immediate"`. Old Workers are rejected during
239
+ The 1.3.0 default is `release_mode="piggyback"`; pass `"immediate"`
240
+ explicitly to release each response through a separate RPC. Old Workers are rejected during
229
241
  capability negotiation if piggyback mode is requested, before any HTTP request
230
242
  is sent. `transport_stats` covers the currently resident pool, not retired Workers.
231
243
 
@@ -55,7 +55,7 @@ def _github_asset_request(release: dict[str, str]) -> urllib.request.Request:
55
55
  if not token:
56
56
  return urllib.request.Request(
57
57
  release["url"],
58
- headers={"User-Agent": "gecko-web-runtime-client/1.2.0"},
58
+ headers={"User-Agent": "gecko-web-runtime-client/1.3.0"},
59
59
  )
60
60
 
61
61
  api = (
@@ -67,7 +67,7 @@ def _github_asset_request(release: dict[str, str]) -> urllib.request.Request:
67
67
  headers={
68
68
  "Accept": "application/vnd.github+json",
69
69
  "Authorization": f"Bearer {token}",
70
- "User-Agent": "gecko-web-runtime-client/1.2.0",
70
+ "User-Agent": "gecko-web-runtime-client/1.3.0",
71
71
  "X-GitHub-Api-Version": "2022-11-28",
72
72
  },
73
73
  )
@@ -85,7 +85,7 @@ def _github_asset_request(release: dict[str, str]) -> urllib.request.Request:
85
85
  headers={
86
86
  "Accept": "application/octet-stream",
87
87
  "Authorization": f"Bearer {token}",
88
- "User-Agent": "gecko-web-runtime-client/1.2.0",
88
+ "User-Agent": "gecko-web-runtime-client/1.3.0",
89
89
  "X-GitHub-Api-Version": "2022-11-28",
90
90
  },
91
91
  )
@@ -60,8 +60,8 @@ def _merge_headers(*groups: Mapping[str, str] | None) -> dict[str, str]:
60
60
  class AsyncWprHttpClient:
61
61
  """Async HTTP client backed by a bounded pool of Gecko Network Workers.
62
62
 
63
- ``max_workers=1`` preserves one Gecko cookie/profile session. Increasing
64
- the bound allows simultaneous requests through separate Worker sessions;
63
+ Defaults use one Gecko cookie/profile session and up to twenty Channels.
64
+ Increasing the Worker bound adds independent concurrent Worker sessions;
65
65
  each slot has its own Gecko CookieService/profile state.
66
66
  """
67
67
 
@@ -75,9 +75,9 @@ class AsyncWprHttpClient:
75
75
  timeout: float | Timeout | None = 30.0,
76
76
  follow_redirects: bool = True,
77
77
  max_workers: int = 1,
78
- release_mode: str = "immediate",
79
- ipc_backend: str = "threaded",
80
- max_channels_per_worker: int = 1,
78
+ release_mode: str = "piggyback",
79
+ ipc_backend: str = "iocp",
80
+ max_channels_per_worker: int = 20,
81
81
  ) -> None:
82
82
  try:
83
83
  worker_limit = integer_index(max_workers)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gecko-web-runtime-client
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: Thin Python client for the Firefox-derived WPR Gecko Worker protocol
5
5
  Author: WPR project
6
6
  License: MPL-2.0-compatible client; see the runtime bundle notices
@@ -11,6 +11,12 @@ Requires-Dist: loguru>=0.7.2; extra == "diagnostics"
11
11
 
12
12
  # Python client
13
13
 
14
+ Version `1.3.0` defaults to one Worker, 20 Channels,
15
+ `ipc_backend="iocp"` and `release_mode="piggyback"`. Published version 1.2.0
16
+ still defaults to one Channel, threaded IPC and immediate release. Runtime
17
+ 155.0.5 is required for the new defaults. Existing 1.2.0 installations keep
18
+ their behavior until explicitly upgraded.
19
+
14
20
  The client provides a standard-library core plus an optional Loguru-backed
15
21
  diagnostics layer. From this directory:
16
22
 
@@ -66,16 +72,17 @@ helpers), `network/transport.py` (the versioned Worker boundary),
66
72
 
67
73
  `timeout` accepts seconds, `Timeout(total=seconds, pool=seconds)`, or `None`.
68
74
  `total` covers queueing plus the active request; `pool` can bound waiting for
69
- an available Worker slot. By default `max_workers=1`, so `asyncio.gather()` calls
70
- on one client queue behind one Worker. Set `max_workers=N` to let the same
71
- client instance dispatch up to N requests at once:
75
+ an available request slot. The 1.3.0 default is one Worker with 20
76
+ concurrent Channels. `asyncio.gather()` submits the work; the client limits
77
+ active requests to `max_workers * max_channels_per_worker`. No arguments are
78
+ needed to discover the installed runtime and enable the default transport:
72
79
 
73
80
  ```python
74
81
  import asyncio
75
82
  from gecko_web_runtime import AsyncWprHttpClient
76
83
 
77
84
  async def main():
78
- async with AsyncWprHttpClient(max_workers=4, timeout=30) as client:
85
+ async with AsyncWprHttpClient() as client:
79
86
  responses = await asyncio.gather(
80
87
  *(client.get(f"https://example.com/api/{i}") for i in range(8))
81
88
  )
@@ -87,8 +94,8 @@ async def main():
87
94
  asyncio.run(main())
88
95
  ```
89
96
 
90
- This is a bounded Gecko Worker pool, not an HTTP socket-connection limit: the
91
- current named-pipe RPC accepts one in-flight request per Worker. Each extra
97
+ Channels bound in-flight requests, not HTTP sockets or Python threads. Set
98
+ `max_channels_per_worker` to change the single-Worker limit. Each extra
92
99
  Worker is a separate Firefox process/profile and therefore has its own Gecko
93
100
  CookieService state; multi-Worker cookie continuity is not shared or ordered.
94
101
  Keep the default `max_workers=1` when requests depend on a single browser cookie
@@ -96,12 +103,14 @@ jar or when minimizing memory is more important than parallel throughput. The
96
103
  pool grows lazily up to the configured cap and reuses Workers after requests.
97
104
  For latency-sensitive bursts, call `await client.warmup(url)` immediately after
98
105
  entering the client and before sending application requests. It starts the
99
- remaining Workers and makes one full GET per Worker to the supplied URL; the
106
+ remaining Workers and makes one full GET per Channel slot to the supplied URL; the
100
107
  responses are read and released while the Worker connections stay open. This
101
108
  is real traffic, so use a safe, idempotent endpoint. Cookies set by that
102
- endpoint remain isolated in each Worker profile.
103
- An active client-side timeout or cancellation stops that Worker because the
104
- current protocol has no per-request cancellation; the next call replaces it.
109
+ endpoint remain isolated in each Worker profile. With the new defaults a
110
+ warmup call makes 20 real GETs; entering a client by itself makes none.
111
+ Active timeout/cancellation in the default multiplexed mode cancels only its
112
+ request Channel. Explicit legacy single-Channel mode stops the Worker and
113
+ the next request replaces it.
105
114
  A queued request timeout leaves active requests and Workers untouched.
106
115
  Connect/read/write phase timeouts still need native Worker support.
107
116
 
@@ -127,8 +136,9 @@ completes. Set `WPR_RUNTIME_HOME`, `WPR_RUNTIME_DIR`, and
127
136
 
128
137
  Client 1.2.0 with runtime 155.0.5 supports `ipc_backend="iocp"` and
129
138
  `max_channels_per_worker=10` with `max_workers=1`, keeping one shared
130
- cookie/proxy session while issuing concurrent Necko requests. Defaults remain
131
- the independent-Worker threaded path. Older runtimes lack these capabilities;
139
+ cookie/proxy session while issuing concurrent Necko requests. Version 1.2.0
140
+ uses explicit opt-in; version 1.3.0 selects these features by default.
141
+ Older runtimes lack these capabilities;
132
142
  upgrade both the client and runtime before enabling multi-Channel requests.
133
143
  See [selection, protocol, and reproducible build instructions](../source/gecko-net-worker/experiments/multiplex-network/README.md).
134
144
 
@@ -151,7 +161,8 @@ exact instantaneous maxima, or a claim of equivalent physical RAM consumption.
151
161
  See [results, limitations, and reproduction commands](tests/results/http-resource-comparison-20261011.md).
152
162
  The test entry points are `tests/integration/baidu_live_ab.py` and
153
163
  `tests/integration/baidu_resource_ab.py`. They remain development tests; the
154
- release keeps opt-in concurrency and transport defaults unchanged.
164
+ measurements refer to the released 1.2.0 configuration, not a claim that
165
+ the 1.3.0 defaults have identical resource costs.
155
166
 
156
167
  ## Network IPC diagnostics and pipe A/B
157
168
 
@@ -222,7 +233,7 @@ $env:WPR_PIPE_MODE = 'persistent'
222
233
  ```
223
234
 
224
235
  ```python
225
- async with AsyncWprHttpClient(max_workers=10, release_mode="piggyback") as client:
236
+ async with AsyncWprHttpClient() as client:
226
237
  response = await client.get("http://127.0.0.1:8080/")
227
238
  body = await response.aread()
228
239
  await client.flush_releases() # Optional explicit Worker-side confirmation.
@@ -236,7 +247,8 @@ pipe occupancy can delay it. Thresholds of 32 entries or 8 MiB trigger drains;
236
247
  they are not global caps on unread response memory. Only acknowledged entries
237
248
  are removed from the pending queue. Abort stops the Worker and discards its queue.
238
249
 
239
- The default remains `release_mode="immediate"`. Old Workers are rejected during
250
+ The 1.3.0 default is `release_mode="piggyback"`; pass `"immediate"`
251
+ explicitly to release each response through a separate RPC. Old Workers are rejected during
240
252
  capability negotiation if piggyback mode is requested, before any HTTP request
241
253
  is sent. `transport_stats` covers the currently resident pool, not retired Workers.
242
254
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "gecko-web-runtime-client"
7
- version = "1.2.0"
7
+ version = "1.3.0"
8
8
  description = "Thin Python client for the Firefox-derived WPR Gecko Worker protocol"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"