From e5fcea3b414b029743a169d414ef153207ccb50a Mon Sep 17 00:00:00 2001
From: sacOO7 <sachinshinde7676@gmail.com>
Date: Fri, 29 Sep 2023 23:00:23 +0530
Subject: [PATCH] closed eventloop thread properly as a part of close method

---
 ably/executer/eventloop.py | 12 +++++++-----
 ably/http/http.py          |  2 ++
 ably/rest/rest.py          |  5 +++--
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/ably/executer/eventloop.py b/ably/executer/eventloop.py
index b1b56cc7..cfa7fb4c 100644
--- a/ably/executer/eventloop.py
+++ b/ably/executer/eventloop.py
@@ -14,13 +14,14 @@ def __init__(self):
 
     @staticmethod
     def get_global() -> 'AblyEventLoop':
-        if AblyEventLoop.__global_event_loop is None:
+        if (AblyEventLoop.__global_event_loop is None or
+                AblyEventLoop.__global_event_loop.loop.is_closed()):
             AblyEventLoop.__global_event_loop = AblyEventLoop()
             AblyEventLoop.__global_event_loop.__create_if_not_exist()
         return AblyEventLoop.__global_event_loop
 
     def __create_if_not_exist(self):
-        if self.loop is None:
+        if self.loop is None or self.loop.is_closed():
             self.loop = asyncio.new_event_loop()
         if not self.loop.is_running():
             self.thread = threading.Thread(
@@ -29,7 +30,8 @@ def __create_if_not_exist(self):
             self.thread.start()
 
     def close(self) -> events:
-        self.loop.stop()
+        # https://stackoverflow.com/questions/46093238/python-asyncio-event-loop-does-not-seem-to-stop-when-stop-method-is-called
+        self.loop.call_soon_threadsafe(self.loop.stop)
+        self.thread.join()
         self.loop.close()
-        self.loop = None
-        self.thread = None
+
diff --git a/ably/http/http.py b/ably/http/http.py
index e47ffb8f..2c4b4e48 100644
--- a/ably/http/http.py
+++ b/ably/http/http.py
@@ -7,6 +7,7 @@
 import httpx
 import msgpack
 
+from ably.decorator.sync import optional_sync
 from ably.rest.auth import Auth
 from ably.http.httputils import HttpUtils
 from ably.transport.defaults import Defaults
@@ -131,6 +132,7 @@ def __init__(self, ably, options):
         self.__host_expires = None
         self.__client = httpx.AsyncClient(http2=True)
 
+    @optional_sync
     async def close(self):
         await self.__client.aclose()
 
diff --git a/ably/rest/rest.py b/ably/rest/rest.py
index 76bcda8a..6fd8f3a1 100644
--- a/ably/rest/rest.py
+++ b/ably/rest/rest.py
@@ -154,10 +154,11 @@ async def __aexit__(self, *excinfo):
     def __exit__(self, *excinfo):
         self.close_sync()
 
-    @optional_sync
     async def close(self):
         await self.http.close()
+        AblyEventLoop.get_global().close()
 
     def close_sync(self):
-        self.close()
+        self.http.close()
         AblyEventLoop.get_global().close()
+