Forcefully stop the CLI server without graceful cleanup. Use this when :meth:`stop` fails or takes too long. This method: - Clears all sessions immediately without destroying them - Force closes the connection (closes the underlying transport) - Kills the CL
(self)
| 1595 | raise ExceptionGroup("errors during CopilotClient.stop()", errors) |
| 1596 | |
| 1597 | async def force_stop(self) -> None: |
| 1598 | """ |
| 1599 | Forcefully stop the CLI server without graceful cleanup. |
| 1600 | |
| 1601 | Use this when :meth:`stop` fails or takes too long. This method: |
| 1602 | - Clears all sessions immediately without destroying them |
| 1603 | - Force closes the connection (closes the underlying transport) |
| 1604 | - Kills the CLI process (if spawned by this client) |
| 1605 | |
| 1606 | Example: |
| 1607 | >>> # If normal stop hangs, force stop |
| 1608 | >>> try: |
| 1609 | ... await asyncio.wait_for(client.stop(), timeout=5.0) |
| 1610 | ... except asyncio.TimeoutError: |
| 1611 | ... await client.force_stop() |
| 1612 | """ |
| 1613 | # Clear sessions immediately without trying to destroy them |
| 1614 | with self._sessions_lock: |
| 1615 | self._sessions.clear() |
| 1616 | |
| 1617 | # Close the transport first to signal the server immediately. |
| 1618 | # For external servers (TCP), this closes the socket. |
| 1619 | # For spawned processes (stdio), this kills the process. |
| 1620 | if self._process is not None or self._cli_process is not None: |
| 1621 | try: |
| 1622 | if self._is_external_server: |
| 1623 | if self._process is not None: |
| 1624 | self._process.terminate() # closes the TCP socket |
| 1625 | self._process = None |
| 1626 | self._cli_process = None |
| 1627 | else: |
| 1628 | if self._process is not None and self._process is not self._cli_process: |
| 1629 | self._process.terminate() |
| 1630 | if self._cli_process is not None: |
| 1631 | self._cli_process.kill() |
| 1632 | self._process = None |
| 1633 | self._cli_process = None |
| 1634 | except Exception: |
| 1635 | logger.debug("Error while force-stopping Copilot CLI process", exc_info=True) |
| 1636 | |
| 1637 | # Then clean up the JSON-RPC client |
| 1638 | if self._client: |
| 1639 | try: |
| 1640 | await self._client.stop() |
| 1641 | except Exception: |
| 1642 | logger.debug( |
| 1643 | "Error while stopping JSON-RPC client during force stop", exc_info=True |
| 1644 | ) |
| 1645 | self._client = None |
| 1646 | self._rpc = None |
| 1647 | |
| 1648 | # Clear models cache |
| 1649 | async with self._models_cache_lock: |
| 1650 | self._models_cache = None |
| 1651 | |
| 1652 | self._state = "disconnected" |
| 1653 | if not self._is_external_server: |
| 1654 | self._runtime_port = None |