|
11 | 11 |
|
12 | 12 | libtmux provides two complementary async patterns: |
13 | 13 |
|
14 | | -**Pattern A**: `.acmd()` methods on Server/Session/Window/Pane objects:: |
| 14 | +**Pattern A**: `.acmd()` methods on Server/Session/Window/Pane objects: |
15 | 15 |
|
16 | | - import asyncio |
17 | | - import libtmux |
| 16 | +>>> import asyncio |
| 17 | +>>> async def example(): |
| 18 | +... # Uses 'server' fixture from conftest |
| 19 | +... result = await server.acmd('list-sessions') |
| 20 | +... return isinstance(result.stdout, list) |
| 21 | +>>> asyncio.run(example()) |
| 22 | +True |
18 | 23 |
|
19 | | - async def example(): |
20 | | - server = libtmux.Server() |
21 | | - result = await server.acmd('list-sessions') |
22 | | - return result.stdout |
| 24 | +**Pattern B**: Direct async execution with `tmux_cmd_async()`: |
23 | 25 |
|
24 | | - asyncio.run(example()) |
25 | | - # Returns: [...] |
26 | | -
|
27 | | -**Pattern B**: Direct async execution with `tmux_cmd_async()`:: |
28 | | -
|
29 | | - import asyncio |
30 | | - from libtmux.common_async import tmux_cmd_async |
31 | | -
|
32 | | - async def example(): |
33 | | - result = await tmux_cmd_async('list-sessions') |
34 | | - return result.stdout |
35 | | -
|
36 | | - asyncio.run(example()) |
37 | | - # Returns: [...] |
| 26 | +>>> async def example_b(): |
| 27 | +... # Uses test server socket for isolation |
| 28 | +... result = await tmux_cmd_async('-L', server.socket_name, 'list-sessions') |
| 29 | +... return isinstance(result.stdout, list) |
| 30 | +>>> asyncio.run(example_b()) |
| 31 | +True |
38 | 32 |
|
39 | 33 | Both patterns preserve 100% of the synchronous API. See the quickstart guide |
40 | 34 | for more information: https://libtmux.git-pull.com/quickstart_async.html |
41 | 35 |
|
42 | 36 | Performance |
43 | 37 | ----------- |
44 | 38 |
|
45 | | -Async provides significant performance benefits for concurrent operations:: |
46 | | -
|
47 | | - import asyncio |
48 | | - from libtmux.common_async import tmux_cmd_async |
| 39 | +Async provides significant performance benefits for concurrent operations: |
49 | 40 |
|
50 | | - async def concurrent(): |
51 | | - # 2-3x faster than sequential execution |
52 | | - results = await asyncio.gather( |
53 | | - tmux_cmd_async('list-sessions'), |
54 | | - tmux_cmd_async('list-windows'), |
55 | | - tmux_cmd_async('list-panes'), |
56 | | - ) |
57 | | - return results |
58 | | -
|
59 | | - asyncio.run(concurrent()) |
| 41 | +>>> async def concurrent(): |
| 42 | +... # 2-3x faster than sequential execution |
| 43 | +... sock = server.socket_name |
| 44 | +... results = await asyncio.gather( |
| 45 | +... tmux_cmd_async('-L', sock, 'list-sessions'), |
| 46 | +... tmux_cmd_async('-L', sock, 'list-windows', '-a'), |
| 47 | +... tmux_cmd_async('-L', sock, 'list-panes', '-a'), |
| 48 | +... ) |
| 49 | +... return len(results) == 3 |
| 50 | +>>> asyncio.run(concurrent()) |
| 51 | +True |
60 | 52 |
|
61 | 53 | See Also |
62 | 54 | -------- |
@@ -260,48 +252,37 @@ class tmux_cmd_async: |
260 | 252 | -------- |
261 | 253 | **Basic Usage**: Execute a single tmux command asynchronously: |
262 | 254 |
|
263 | | - >>> import asyncio |
264 | | - >>> async def main(): |
265 | | - ... proc = await tmux_cmd_async(f'-L{server.socket_name}', 'new-session', '-d', '-P', '-F#S') |
266 | | - ... if proc.stderr: |
267 | | - ... raise exc.LibTmuxException( |
268 | | - ... 'Command: %s returned error: %s' % (proc.cmd, proc.stderr) |
269 | | - ... ) |
270 | | - ... print(f'tmux command returned {" ".join(proc.stdout)}') |
271 | | - >>> asyncio.run(main()) |
272 | | - tmux command returned 2 |
273 | | -
|
274 | | - **Concurrent Operations**: Execute multiple commands in parallel for 2-3x speedup:: |
275 | | -
|
276 | | - import asyncio |
277 | | - from libtmux.common_async import tmux_cmd_async |
278 | | -
|
279 | | - async def concurrent_example(): |
280 | | - # All commands run concurrently |
281 | | - results = await asyncio.gather( |
282 | | - tmux_cmd_async('list-sessions'), |
283 | | - tmux_cmd_async('list-windows'), |
284 | | - tmux_cmd_async('list-panes'), |
285 | | - ) |
286 | | - return [len(r.stdout) for r in results] |
287 | | -
|
288 | | - asyncio.run(concurrent_example()) |
289 | | - # Returns: [...] |
290 | | -
|
291 | | - **Error Handling**: Check return codes and stderr:: |
292 | | -
|
293 | | - import asyncio |
294 | | - from libtmux.common_async import tmux_cmd_async |
295 | | -
|
296 | | - async def check_session(): |
297 | | - result = await tmux_cmd_async('has-session', '-t', 'my_session') |
298 | | - if result.returncode != 0: |
299 | | - print("Session doesn't exist") |
300 | | - return False |
301 | | - return True |
302 | | -
|
303 | | - asyncio.run(check_session()) |
304 | | - # Returns: False |
| 255 | + >>> async def basic_example(): |
| 256 | + ... # Execute command with isolated socket |
| 257 | + ... proc = await tmux_cmd_async('-L', server.socket_name, 'new-session', '-d', '-P', '-F#S') |
| 258 | + ... # Verify command executed successfully |
| 259 | + ... return len(proc.stdout) > 0 and not proc.stderr |
| 260 | + >>> asyncio.run(basic_example()) |
| 261 | + True |
| 262 | +
|
| 263 | + **Concurrent Operations**: Execute multiple commands in parallel for 2-3x speedup: |
| 264 | +
|
| 265 | + >>> async def concurrent_example(): |
| 266 | + ... # All commands run concurrently |
| 267 | + ... sock = server.socket_name |
| 268 | + ... results = await asyncio.gather( |
| 269 | + ... tmux_cmd_async('-L', sock, 'list-sessions'), |
| 270 | + ... tmux_cmd_async('-L', sock, 'list-windows', '-a'), |
| 271 | + ... tmux_cmd_async('-L', sock, 'list-panes', '-a'), |
| 272 | + ... ) |
| 273 | + ... return all(isinstance(r.stdout, list) for r in results) |
| 274 | + >>> asyncio.run(concurrent_example()) |
| 275 | + True |
| 276 | +
|
| 277 | + **Error Handling**: Check return codes and stderr: |
| 278 | +
|
| 279 | + >>> async def check_session(): |
| 280 | + ... # Non-existent session returns non-zero returncode |
| 281 | + ... sock = server.socket_name |
| 282 | + ... result = await tmux_cmd_async('-L', sock, 'has-session', '-t', 'nonexistent_12345') |
| 283 | + ... return result.returncode != 0 |
| 284 | + >>> asyncio.run(check_session()) |
| 285 | + True |
305 | 286 |
|
306 | 287 | Equivalent to: |
307 | 288 |
|
@@ -425,32 +406,25 @@ async def get_version() -> LooseVersion: |
425 | 406 |
|
426 | 407 | Examples |
427 | 408 | -------- |
428 | | - Get tmux version asynchronously:: |
429 | | -
|
430 | | - import asyncio |
431 | | - from libtmux.common_async import get_version |
432 | | -
|
433 | | - async def check_version(): |
434 | | - version = await get_version() |
435 | | - print(f"tmux version: {version}") |
436 | | -
|
437 | | - asyncio.run(check_version()) |
438 | | - # Prints: tmux version: 3.4 |
439 | | -
|
440 | | - Use in concurrent operations:: |
441 | | -
|
442 | | - import asyncio |
443 | | - from libtmux.common_async import get_version, tmux_cmd_async |
444 | | -
|
445 | | - async def check_all(): |
446 | | - version, sessions = await asyncio.gather( |
447 | | - get_version(), |
448 | | - tmux_cmd_async('list-sessions'), |
449 | | - ) |
450 | | - return version, len(sessions.stdout) |
451 | | -
|
452 | | - asyncio.run(check_all()) |
453 | | - # Returns: (LooseVersion('3.4'), 2) |
| 409 | + Get tmux version asynchronously: |
| 410 | +
|
| 411 | + >>> async def check_version(): |
| 412 | + ... version = await get_version() |
| 413 | + ... return len(str(version)) > 0 |
| 414 | + >>> asyncio.run(check_version()) |
| 415 | + True |
| 416 | +
|
| 417 | + Use in concurrent operations: |
| 418 | +
|
| 419 | + >>> async def check_all(): |
| 420 | + ... sock = server.socket_name |
| 421 | + ... version, sessions = await asyncio.gather( |
| 422 | + ... get_version(), |
| 423 | + ... tmux_cmd_async('-L', sock, 'list-sessions'), |
| 424 | + ... ) |
| 425 | + ... return isinstance(str(version), str) and isinstance(sessions.stdout, list) |
| 426 | + >>> asyncio.run(check_all()) |
| 427 | + True |
454 | 428 |
|
455 | 429 | Returns |
456 | 430 | ------- |
|
0 commit comments