Skip to content

Commit b3827ed

Browse files
authored
Merge pull request #267 from plotly/andrew/further-thread-extraction
Move all process functions to new threadpool executor.
2 parents 4a2ee4f + d436b7d commit b3827ed

File tree

3 files changed

+20
-6
lines changed

3 files changed

+20
-6
lines changed

CHANGELOG.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
v1.2.1
2+
- Use custom threadpool for functions that could be running during shutdown:
3+
Python's stdlib threadpool isn't available during interpreter shutdown, nor
4+
`atexit`- so they cannot be started or shutdown during `atexit`, or relied
5+
upon at all. We use a custom threadpool during `Browser.close()` so that it
6+
can be leveraged during atexit, and now we use it during `Browser.open()`
7+
since certain use patterns have that function running during shutdown.
18
- Remove site directory
29
- Improve error messaging
310
- Organize functions internally

ROADMAP.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
- [ ] Working on better diagnostic information
44
- [ ] Explain to user when their system has security restrictions
55
- [ ] Eliminate synchronous API: it's unused, hard to maintain, and nearly
6-
worthless
6+
worthless
77
- [ ] Diagnose function should collect a JSON and then print that
88
- [ ] Allow user to build and send their own JSONS
99
- [ ] Get serialization out of the lock
10-
- [ ]
1110
- [ ] Support Firefox
1211
- [ ] Support LadyBird (!)
1312
- [ ] Test against multiple docker containers

src/choreographer/browser_async.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ async def close(self) -> None:
4646
class Browser(Target):
4747
"""`Browser` is the async implementation of `Browser`."""
4848

49+
subprocess: subprocess.Popen[bytes] | subprocess.Popen[str]
50+
"""A reference to the `Popen` object."""
51+
4952
tabs: MutableMapping[str, Tab]
5053
"""A mapping by target_id of all the targets which are open tabs."""
5154
targets: MutableMapping[str, Target]
@@ -96,7 +99,7 @@ def __init__(
9699
"""
97100
_logger.debug("Attempting to open new browser.")
98101

99-
self._check_closed_executor = _manual_thread_pool.ManualThreadExecutor(
102+
self._process_executor = _manual_thread_pool.ManualThreadExecutor(
100103
max_workers=3,
101104
name="checking_close",
102105
)
@@ -144,7 +147,10 @@ def run() -> subprocess.Popen[bytes] | subprocess.Popen[str]: # depends on args
144147

145148
_logger.debug("Trying to open browser.")
146149
loop = asyncio.get_running_loop()
147-
self.subprocess = await loop.run_in_executor(None, run)
150+
self.subprocess = await loop.run_in_executor(
151+
self._process_executor,
152+
run,
153+
)
148154

149155
super().__init__("0", self._broker)
150156
self._add_session(Session("", self._broker))
@@ -198,7 +204,7 @@ async def _is_closed(self, wait: int | None = 0) -> bool:
198204
loop = asyncio.get_running_loop()
199205

200206
await loop.run_in_executor(
201-
self._check_closed_executor,
207+
self._process_executor,
202208
self.subprocess.wait,
203209
wait,
204210
)
@@ -250,6 +256,8 @@ async def close(self) -> None:
250256
self._watch_dog_task.cancel()
251257
if not self._release_lock():
252258
return
259+
# it can never be mid open here, because all of these must
260+
# run on the same thread. Do not push open or close to threads.
253261
try:
254262
_logger.debug("Starting browser close methods.")
255263
await self._close()
@@ -267,7 +275,7 @@ async def close(self) -> None:
267275
_logger.debug("Browser channel closed.")
268276
self._browser_impl.clean() # os blocky/hangy across networks
269277
_logger.debug("Browser implementation cleaned up.")
270-
self._check_closed_executor.shutdown(wait=False, cancel_futures=True)
278+
self._process_executor.shutdown(wait=False, cancel_futures=True)
271279

272280
async def __aexit__(
273281
self,

0 commit comments

Comments
 (0)