Skip to content

Commit

Permalink
CHIA-1645: Some daemon start cleanup (#18809)
Browse files Browse the repository at this point in the history
* Some daemon start cleanup

* mypy fixes

* Reduce scopy of change

* typo

* Use *=
  • Loading branch information
emlowe authored Nov 13, 2024
1 parent d9f7108 commit ecdf4f4
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 37 deletions.
15 changes: 6 additions & 9 deletions chia/cmds/start_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ def launch_start_daemon(root_path: Path) -> subprocess.Popen:
print(f"Starting daemon: {cmd_to_execute} run_daemon --wait-for-unlock", flush=True)
process = subprocess.Popen(
[cmd_to_execute, "run_daemon", "--wait-for-unlock"],
encoding="utf-8",
stdout=subprocess.PIPE,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
stdin=subprocess.DEVNULL,
creationflags=creationflags,
start_new_session=True,
)

return process
Expand All @@ -48,13 +50,8 @@ async def create_start_daemon_connection(
if connection is None:
print("Starting daemon", flush=True)
# launch a daemon
process = launch_start_daemon(root_path)
# give the daemon a chance to start up
if process.stdout:
process.stdout.readline()
await asyncio.sleep(1)
# it prints "daemon: listening"
connection = await connect_to_daemon_and_validate(root_path, config)
launch_start_daemon(root_path)
connection = await connect_to_daemon_and_validate(root_path, config, wait_for_start=True)
if connection:
if skip_keyring:
print("Skipping to unlock keyring")
Expand Down
49 changes: 33 additions & 16 deletions chia/daemon/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,30 @@ def format_request(self, command: str, data: dict[str, Any]) -> WsRpcMessage:
request = create_payload_dict(command, data, "client", "daemon")
return request

async def start(self) -> None:
try:
self.client_session = aiohttp.ClientSession()
self.websocket = await self.client_session.ws_connect(
self._uri,
autoclose=True,
autoping=True,
heartbeat=self.heartbeat,
ssl=self.ssl_context if self.ssl_context is not None else True,
max_msg_size=self.max_message_size,
)
except Exception:
async def start(self, wait_for_start: bool = False) -> None:
self.client_session = aiohttp.ClientSession()

connect_backoff = 2
while (self.websocket is None or self.websocket.closed) and connect_backoff <= 60:
try:
self.websocket = await self.client_session.ws_connect(
self._uri,
autoclose=True,
autoping=True,
heartbeat=self.heartbeat,
ssl=self.ssl_context if self.ssl_context is not None else True,
max_msg_size=self.max_message_size,
)
break
except aiohttp.ClientError:
if not wait_for_start:
break
await asyncio.sleep(connect_backoff)
connect_backoff *= 2

if self.websocket is None or self.websocket.closed:
await self.close()
raise
raise Exception("Failed to connect to daemon")

async def listener_task() -> None:
try:
Expand Down Expand Up @@ -161,7 +171,12 @@ async def get_keys_for_plotting(self, fingerprints: Optional[list[uint32]] = Non


async def connect_to_daemon(
self_hostname: str, daemon_port: int, max_message_size: int, ssl_context: ssl.SSLContext, heartbeat: int
self_hostname: str,
daemon_port: int,
max_message_size: int,
ssl_context: ssl.SSLContext,
heartbeat: int,
wait_for_start: bool = False,
) -> DaemonProxy:
"""
Connect to the local daemon.
Expand All @@ -173,12 +188,13 @@ async def connect_to_daemon(
max_message_size=max_message_size,
heartbeat=heartbeat,
)
await client.start()

await client.start(wait_for_start=wait_for_start)
return client


async def connect_to_daemon_and_validate(
root_path: Path, config: dict[str, Any], quiet: bool = False
root_path: Path, config: dict[str, Any], quiet: bool = False, wait_for_start: bool = False
) -> Optional[DaemonProxy]:
"""
Connect to the local daemon and do a ping to ensure that something is really
Expand All @@ -200,6 +216,7 @@ async def connect_to_daemon_and_validate(
max_message_size=daemon_max_message_size,
ssl_context=ssl_context,
heartbeat=daemon_heartbeat,
wait_for_start=wait_for_start,
)
r = await connection.ping()

Expand Down
2 changes: 1 addition & 1 deletion chia/daemon/keychain_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ async def _get(self, request: WsRpcMessage) -> WsRpcMessage:
except asyncio.TimeoutError:
raise KeychainProxyConnectionTimeout()

async def start(self) -> None:
async def start(self, wait_for_start: bool = False) -> None:
self.keychain_connection_task = asyncio.create_task(self.connect_to_keychain())
await self.connection_established.wait() # wait until connection is established.

Expand Down
11 changes: 0 additions & 11 deletions chia/daemon/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -1548,17 +1548,6 @@ async def async_run_daemon(root_path: Path, wait_for_unlock: bool = False) -> in
ca_crt_path = root_path / config["private_ssl_ca"]["crt"]
ca_key_path = root_path / config["private_ssl_ca"]["key"]
sys.stdout.flush()
json_msg = dict_to_json_str(
{
"message": "cert_path",
"success": True,
"cert": f"{crt_path}",
"key": f"{key_path}",
"ca_crt": f"{ca_crt_path}",
}
)
sys.stdout.write("\n" + json_msg + "\n")
sys.stdout.flush()
try:
with Lockfile.create(daemon_launch_lock_path(root_path), timeout=1):
log.info(f"chia-blockchain version: {chia_short_version()}")
Expand Down

0 comments on commit ecdf4f4

Please sign in to comment.