-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from zhulik/handle-down-network
Handle down network
- Loading branch information
Showing
6 changed files
with
97 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,81 @@ | ||
import asyncio | ||
import json | ||
import time | ||
from asyncio.exceptions import TimeoutError as AIOTimeoutError | ||
|
||
from .exceptions import DisconnectedError | ||
|
||
|
||
class Channel: | ||
CHANNEL_URL = "https://channel.tractive.com/3/channel" | ||
IGNORE_MESSAGES = ["handshake", "keep-alive"] | ||
|
||
KEEP_ALIVE_TIMEOUT = 7 # seconds | ||
CHECK_CONNECTION_TIME = 4 # seconds | ||
|
||
def __init__(self, api): | ||
self._api = api | ||
self._last_keep_alive = None | ||
self._listen_task = None | ||
self._check_connection_task = None | ||
self._queue = asyncio.Queue() | ||
|
||
async def listen(self): | ||
self._check_connection_task = asyncio.create_task(self._check_connection()) | ||
self._listen_task = asyncio.create_task(self._listen()) | ||
while True: | ||
event = await self._queue.get() | ||
self._queue.task_done() | ||
|
||
if event["type"] == "event": | ||
yield event["event"] | ||
|
||
if event["type"] == "error": | ||
self._check_connection_task.cancel() | ||
|
||
await self._check_connection_task | ||
raise event["error"] | ||
|
||
if event["type"] == "cancelled": | ||
self._listen_task.cancel() | ||
|
||
await self._listen_task | ||
raise DisconnectedError() from event["error"] | ||
|
||
async def _listen(self): | ||
while True: | ||
try: | ||
async with self._api.session.request( | ||
"POST", self.CHANNEL_URL, headers=await self._api.auth_headers() | ||
"POST", | ||
self.CHANNEL_URL, | ||
headers=await self._api.auth_headers(), | ||
) as response: | ||
async for data, _ in response.content.iter_chunks(): | ||
event = json.loads(data) | ||
if event["message"] == "keep-alive": | ||
self._last_keep_alive = time.time() | ||
continue | ||
if event["message"] in self.IGNORE_MESSAGES: | ||
continue | ||
yield event | ||
await self._queue.put({"type": "event", "event": event}) | ||
except AIOTimeoutError: | ||
continue | ||
except asyncio.CancelledError as error: | ||
await self._queue.put({"type": "cancelled", "error": error}) | ||
return | ||
except Exception as error: # pylint: disable=broad-except | ||
await self._queue.put({"type": "error", "error": error}) | ||
return | ||
|
||
async def _check_connection(self): | ||
try: | ||
while True: | ||
if self._last_keep_alive is not None and ( | ||
time.time() - self._last_keep_alive > self.KEEP_ALIVE_TIMEOUT | ||
): | ||
self._listen_task.cancel() | ||
return | ||
|
||
await asyncio.sleep(self.CHECK_CONNECTION_TIME) | ||
except asyncio.CancelledError: | ||
return |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters