# Buggy code
async def run(self):
    async def _check_parent():
        """Check if raylet is dead and fate-share if it is."""
        try:
            curr_proc = psutil.Process()
            while True:
                parent = curr_proc.parent()
                if parent is None or parent.pid == 1 or self.ppid != parent.pid:
                    logger.error("Raylet is dead, exiting.")
                    sys.exit(0)
                await asyncio.sleep(
                    dashboard_consts.DASHBOARD_AGENT_CHECK_PARENT_INTERVAL_SECONDS
                )
        except Exception:
            logger.error("Failed to check parent PID, exiting.")
            sys.exit(1)

    if sys.platform not in ["win32", "cygwin"]:
        check_parent_task = create_task(_check_parent())

    # Create an aioredis client for all modules.
    try:
        self.aioredis_client = await dashboard_utils.get_aioredis_client(
            self.redis_address,
            self.redis_password,
            dashboard_consts.CONNECT_REDIS_INTERNAL_SECONDS,
            dashboard_consts.RETRY_REDIS_CONNECTION_TIMES,
        )
    except (socket.gaierror, ConnectionRefusedError):
        logger.error(
            "Dashboard agent exiting: Failed to connect to redis at %s",
            self.redis_address,
        )
        sys.exit(-1)

    # Create a http session for all modules.
    self.http_session = aiohttp.ClientSession(loop=asyncio.get_event_loop())

    # Start a grpc asyncio server.
    await self.server.start()

    modules = self._load_modules()

    # Http server should be initialized after all modules loaded.
    app = aiohttp.web.Application()
    app.add_routes(routes=routes.bound_routes())

    # Enable CORS on all routes.
    cors = aiohttp_cors.setup(
        app,
        defaults={
            "*": aiohttp_cors.ResourceOptions(
                allow_credentials=True,
                expose_headers="*",
                allow_methods="*",
                allow_headers=("Content-Type", "X-Header"),
            )
        },
    )
    for route in list(app.router.routes()):
        cors.add(route)

    runner = aiohttp.web.AppRunner(app)
    await runner.setup()
    site = aiohttp.web.TCPSite(runner, self.ip, 0)
    await site.start()
    http_host, http_port = site._server.sockets[0].getsockname()
    logger.info("Dashboard agent http address: %s:%s", http_host, http_port)

    # Dump registered http routes.
    dump_routes = [r for r in app.router.routes() if r.method != hdrs.METH_HEAD]
    for r in dump_routes:
        logger.info(r)
    logger.info("Registered %s routes.", len(dump_routes))

    # Write the dashboard agent port to redis.
    await self.aioredis_client.set(
        f"{dashboard_consts.DASHBOARD_AGENT_PORT_PREFIX}{self.node_id}",
        json.dumps([http_port, self.grpc_port]),
    )

    # Register agent to agent manager.
    raylet_stub = agent_manager_pb2_grpc.AgentManagerServiceStub(
        self.aiogrpc_raylet_channel
    )

    await raylet_stub.RegisterAgent(
        agent_manager_pb2.RegisterAgentRequest(
            agent_pid=os.getpid(), agent_port=self.grpc_port, agent_ip_address=self.ip
        )
    )

    await asyncio.gather(check_parent_task, *(m.run(self.server) for m in modules))
    await self.server.wait_for_termination()
    # Wait for finish signal.
    await runner.cleanup()


# Traceback (UnboundLocalError)
2021-01-05T07:27:22.1039161Z 2021-01-05 07:26:40,486	WARNING worker.py:1044 -- The agent on node fv-az68-689 failed with the following error:
2021-01-05T07:27:22.1039976Z Traceback (most recent call last):
2021-01-05T07:27:22.1040684Z   File "d:\a\ray\ray\python\ray\new_dashboard/agent.py", line 311, in <module>
2021-01-05T07:27:22.1041457Z     loop.run_until_complete(agent.run())
2021-01-05T07:27:22.1043175Z   File "C:\hostedtoolcache\windows\Python\3.7.9\x64\lib\asyncio\base_events.py", line 587, in run_until_complete
2021-01-05T07:27:22.1044233Z     return future.result()
2021-01-05T07:27:22.1044986Z   File "d:\a\ray\ray\python\ray\new_dashboard/agent.py", line 187, in run
2021-01-05T07:27:22.1045759Z     await asyncio.gather(check_parent_task,
2021-01-05T07:27:22.1046632Z UnboundLocalError: local variable 'check_parent_task' referenced before assignment
2021-01-05T07:27:22.1047247Z
2021-01-05T07:27:22.1047797Z �[2m�[36m(pid=None)�[0m Traceback (most recent call last):
2021-01-05T07:27:22.1048322Z
2021-01-05T07:27:22.1049013Z �[2m�[36m(pid=None)�[0m   File "d:\a\ray\ray\python\ray\new_dashboard/agent.py", line 322, in <module>
2021-01-05T07:27:22.1049555Z
2021-01-05T07:27:22.1050018Z �[2m�[36m(pid=None)�[0m     raise e
2021-01-05T07:27:22.1050352Z
2021-01-05T07:27:22.1050980Z �[2m�[36m(pid=None)�[0m   File "d:\a\ray\ray\python\ray\new_dashboard/agent.py", line 311, in <module>
2021-01-05T07:27:22.1051524Z
2021-01-05T07:27:22.1052129Z �[2m�[36m(pid=None)�[0m     loop.run_until_complete(agent.run())
2021-01-05T07:27:22.1052559Z
2021-01-05T07:27:22.1053390Z �[2m�[36m(pid=None)�[0m   File "C:\hostedtoolcache\windows\Python\3.7.9\x64\lib\asyncio\base_events.py", line 587, in run_until_complete
2021-01-05T07:27:22.1054078Z
2021-01-05T07:27:22.1054625Z �[2m�[36m(pid=None)�[0m     return future.result()
2021-01-05T07:27:22.1055026Z
2021-01-05T07:27:22.1055681Z �[2m�[36m(pid=None)�[0m   File "d:\a\ray\ray\python\ray\new_dashboard/agent.py", line 187, in run
2021-01-05T07:27:22.1056156Z
2021-01-05T07:27:22.1056751Z �[2m�[36m(pid=None)�[0m     await asyncio.gather(check_parent_task,
2021-01-05T07:27:22.1057213Z
2021-01-05T07:27:22.1058008Z �[2m�[36m(pid=None)�[0m UnboundLocalError: local variable 'check_parent_task' referenced before assignment
2021-01-05T07:27:22.1058653Z
2021-01-05T07:27:22.1059146Z �[2m�[36m(pid=None)�[0m --- Logging error ---
2021-01-05T07:27:22.1059512Z
2021-01-05T07:27:22.1060051Z �[2m�[36m(pid=None)�[0m Traceback (most recent call last):
2021-01-05T07:27:22.1060458Z
2021-01-05T07:27:22.1061184Z �[2m�[36m(pid=None)�[0m   File "C:\hostedtoolcache\windows\Python\3.7.9\x64\lib\logging\handlers.py", line 69, in emit
2021-01-05T07:27:22.1072363Z
2021-01-05T07:27:22.1073081Z �[2m�[36m(pid=None)�[0m     if self.shouldRollover(record):
2021-01-05T07:27:22.1073557Z
2021-01-05T07:27:22.1074417Z �[2m�[36m(pid=None)�[0m   File "C:\hostedtoolcache\windows\Python\3.7.9\x64\lib\logging\handlers.py", line 183, in shouldRollover
2021-01-05T07:27:22.1075116Z
2021-01-05T07:27:22.1075651Z �[2m�[36m(pid=None)�[0m     self.stream = self._open()
2021-01-05T07:27:22.1076051Z
2021-01-05T07:27:22.1076745Z �[2m�[36m(pid=None)�[0m   File "C:\hostedtoolcache\windows\Python\3.7.9\x64\lib\logging\__init__.py", line 1116, in _open
2021-01-05T07:27:22.1077345Z
2021-01-05T07:27:22.1078106Z �[2m�[36m(pid=None)�[0m     return open(self.baseFilename, self.mode, encoding=self.encoding)
2021-01-05T07:27:22.1078730Z
2021-01-05T07:27:22.1079292Z �[2m�[36m(pid=None)�[0m NameError: name 'open' is not defined
2021-01-05T07:27:22.1079708Z
2021-01-05T07:27:22.1080172Z �[2m�[36m(pid=None)�[0m Call stack:
2021-01-05T07:27:22.1080503Z
2021-01-05T07:27:22.1082589Z �[2m�[36m(pid=None)�[0m   File "C:\hostedtoolcache\windows\Python\3.7.9\x64\lib\site-packages\aiohttp\client.py", line 320, in __del__
2021-01-05T07:27:22.1083331Z
2021-01-05T07:27:22.1083952Z �[2m�[36m(pid=None)�[0m     self._loop.call_exception_handler(context)
2021-01-05T07:27:22.1084419Z
2021-01-05T07:27:22.1085281Z �[2m�[36m(pid=None)�[0m   File "C:\hostedtoolcache\windows\Python\3.7.9\x64\lib\asyncio\base_events.py", line 1645, in call_exception_handler
2021-01-05T07:27:22.1085985Z
2021-01-05T07:27:22.1086595Z �[2m�[36m(pid=None)�[0m     self.default_exception_handler(context)
2021-01-05T07:27:22.1087071Z
2021-01-05T07:27:22.1087942Z �[2m�[36m(pid=None)�[0m   File "C:\hostedtoolcache\windows\Python\3.7.9\x64\lib\asyncio\base_events.py", line 1619, in default_exception_handler
2021-01-05T07:27:22.1088655Z
2021-01-05T07:27:22.1089225Z �[2m�[36m(pid=None)�[0m     logger.error('\n'.join(log_lines), exc_info=exc_info)
2021-01-05T07:27:22.1089710Z
2021-01-05T07:27:22.1090674Z �[2m�[36m(pid=None)�[0m Message: 'Unclosed client session\nclient_session: <aiohttp.client.ClientSession object at 0x000002699DFEAE88>'
2021-01-05T07:27:22.1091493Z
2021-01-05T07:27:22.1091965Z �[2m�[36m(pid=None)�[0m Arguments: ()

# Fixed code
async def run(self):
    async def _check_parent():
        """Check if raylet is dead and fate-share if it is."""
        try:
            curr_proc = psutil.Process()
            while True:
                parent = curr_proc.parent()
                if parent is None or parent.pid == 1 or self.ppid != parent.pid:
                    logger.error("Raylet is dead, exiting.")
                    sys.exit(0)
                await asyncio.sleep(
                    dashboard_consts.DASHBOARD_AGENT_CHECK_PARENT_INTERVAL_SECONDS
                )
        except Exception:
            logger.error("Failed to check parent PID, exiting.")
            sys.exit(1)

    check_parent_task = create_task(_check_parent())

    # Create an aioredis client for all modules.
    try:
        self.aioredis_client = await dashboard_utils.get_aioredis_client(
            self.redis_address,
            self.redis_password,
            dashboard_consts.CONNECT_REDIS_INTERNAL_SECONDS,
            dashboard_consts.RETRY_REDIS_CONNECTION_TIMES,
        )
    except (socket.gaierror, ConnectionRefusedError):
        logger.error(
            "Dashboard agent exiting: Failed to connect to redis at %s",
            self.redis_address,
        )
        sys.exit(-1)

    # Create a http session for all modules.
    self.http_session = aiohttp.ClientSession(loop=asyncio.get_event_loop())

    # Start a grpc asyncio server.
    await self.server.start()

    modules = self._load_modules()

    # Http server should be initialized after all modules loaded.
    app = aiohttp.web.Application()
    app.add_routes(routes=routes.bound_routes())

    # Enable CORS on all routes.
    cors = aiohttp_cors.setup(
        app,
        defaults={
            "*": aiohttp_cors.ResourceOptions(
                allow_credentials=True,
                expose_headers="*",
                allow_methods="*",
                allow_headers=("Content-Type", "X-Header"),
            )
        },
    )
    for route in list(app.router.routes()):
        cors.add(route)

    runner = aiohttp.web.AppRunner(app)
    await runner.setup()
    site = aiohttp.web.TCPSite(runner, self.ip, 0)
    await site.start()
    http_host, http_port = site._server.sockets[0].getsockname()
    logger.info("Dashboard agent http address: %s:%s", http_host, http_port)

    # Dump registered http routes.
    dump_routes = [r for r in app.router.routes() if r.method != hdrs.METH_HEAD]
    for r in dump_routes:
        logger.info(r)
    logger.info("Registered %s routes.", len(dump_routes))

    # Write the dashboard agent port to redis.
    await self.aioredis_client.set(
        f"{dashboard_consts.DASHBOARD_AGENT_PORT_PREFIX}{self.node_id}",
        json.dumps([http_port, self.grpc_port]),
    )

    # Register agent to agent manager.
    raylet_stub = agent_manager_pb2_grpc.AgentManagerServiceStub(
        self.aiogrpc_raylet_channel
    )

    await raylet_stub.RegisterAgent(
        agent_manager_pb2.RegisterAgentRequest(
            agent_pid=os.getpid(), agent_port=self.grpc_port, agent_ip_address=self.ip
        )
    )

    await asyncio.gather(check_parent_task, *(m.run(self.server) for m in modules))
    await self.server.wait_for_termination()
    # Wait for finish signal.
    await runner.cleanup()