Clean up Connection and add logging
This commit is contained in:
parent
3b3ce99625
commit
aee8e5c118
1 changed files with 64 additions and 26 deletions
|
|
@ -1,10 +1,13 @@
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
import websocket
|
import websocket
|
||||||
from websocket import WebSocketException as WSException
|
from websocket import WebSocketException as WSException
|
||||||
|
|
||||||
from . import callbacks
|
from .callbacks import Callbacks
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class Connection():
|
class Connection():
|
||||||
"""
|
"""
|
||||||
|
|
@ -24,15 +27,13 @@ class Connection():
|
||||||
|
|
||||||
def __init__(self, room, url_format=None):
|
def __init__(self, room, url_format=None):
|
||||||
"""
|
"""
|
||||||
room - name of the room to connect to
|
room - name of the room to connect to
|
||||||
|
url_format - url the bot will connect to, where the room name is represented by {}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.room = room
|
self.room = room
|
||||||
|
|
||||||
if not url_format:
|
self._url_format = url_format or ROOM_FORMAT
|
||||||
url_format = self.ROOM_FORMAT
|
|
||||||
self._url = url_format.format(self.room)
|
|
||||||
|
|
||||||
self._stopping = False
|
self._stopping = False
|
||||||
|
|
||||||
|
|
@ -46,8 +47,9 @@ class Connection():
|
||||||
"""
|
"""
|
||||||
_connect(tries, delay) -> bool
|
_connect(tries, delay) -> bool
|
||||||
|
|
||||||
tries - maximum number of retries
|
delay - delay between retries (in seconds)
|
||||||
-1 -> retry indefinitely
|
tries - maximum number of retries
|
||||||
|
-1 -> retry indefinitely
|
||||||
|
|
||||||
Returns True on success, False on failure.
|
Returns True on success, False on failure.
|
||||||
|
|
||||||
|
|
@ -56,48 +58,62 @@ class Connection():
|
||||||
|
|
||||||
while tries != 0:
|
while tries != 0:
|
||||||
try:
|
try:
|
||||||
|
url = self._url_format.format(self.room)
|
||||||
|
logger.log("Connecting to url: {!r}".format(url))
|
||||||
|
logger.debug("{} {} left".format(
|
||||||
|
tries-1 if tries>0 else "infinite",
|
||||||
|
"tries" if tries!=1 else "try" # proper english :D
|
||||||
|
))
|
||||||
self._ws = websocket.create_connection(
|
self._ws = websocket.create_connection(
|
||||||
self._url,
|
url,
|
||||||
enable_multithread=True
|
enable_multithread=True
|
||||||
)
|
)
|
||||||
|
|
||||||
self._callbacks.call("connect")
|
|
||||||
|
|
||||||
return True
|
|
||||||
except WSException:
|
except WSException:
|
||||||
if tries > 0:
|
if tries > 0:
|
||||||
tries -= 1
|
tries -= 1
|
||||||
if tries != 0:
|
if tries != 0:
|
||||||
|
logger.log("Connection failed. Retrying in {} seconds.".format(delay))
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
|
|
||||||
|
else:
|
||||||
|
logger.debug("Connected")
|
||||||
|
self._callbacks.call("connect")
|
||||||
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
"""
|
"""
|
||||||
disconnect() -> None
|
disconnect() -> None
|
||||||
|
|
||||||
Reconnect to the room.
|
Disconnect from the room.
|
||||||
WARNING: To completely disconnect, use stop().
|
This will cause the connection to reconnect.
|
||||||
|
To completely disconnect, use stop().
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self._ws:
|
if self._ws:
|
||||||
self._ws.close()
|
self._ws.close()
|
||||||
self._ws = None
|
self._ws = None
|
||||||
|
|
||||||
|
logger.debug("Disconnected")
|
||||||
self._callbacks.call("disconnect")
|
self._callbacks.call("disconnect")
|
||||||
|
|
||||||
def launch(self):
|
def launch(self):
|
||||||
"""
|
"""
|
||||||
launch() -> Thread
|
launch() -> Thread
|
||||||
|
|
||||||
Connect to the room and spawn a new thread running run.
|
Connect to the room and spawn a new thread.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self._connect(tries=1):
|
if self._connect(tries=1):
|
||||||
self._thread = threading.Thread(target=self._run,
|
self._thread = threading.Thread(target=self._run,
|
||||||
name="{}-{}".format(self.room, int(time.time())))
|
name="{}-{}".format(self.room, int(time.time())))
|
||||||
|
logger.debug("Launching new thread: {}".format(self._thread.name))
|
||||||
self._thread.start()
|
self._thread.start()
|
||||||
return self._thread
|
return self._thread
|
||||||
else:
|
else:
|
||||||
|
logger.debug("Room probably doesn't exist.");
|
||||||
self.stop()
|
self.stop()
|
||||||
|
|
||||||
def _run(self):
|
def _run(self):
|
||||||
|
|
@ -107,6 +123,7 @@ class Connection():
|
||||||
Receive messages.
|
Receive messages.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
logger.debug("Running")
|
||||||
while not self._stopping:
|
while not self._stopping:
|
||||||
try:
|
try:
|
||||||
self._handle_json(self._ws.recv())
|
self._handle_json(self._ws.recv())
|
||||||
|
|
@ -123,6 +140,7 @@ class Connection():
|
||||||
Joins the thread launched by self.launch().
|
Joins the thread launched by self.launch().
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
logger.debug("Stopping")
|
||||||
self._stopping = True
|
self._stopping = True
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
|
|
||||||
|
|
@ -131,6 +149,28 @@ class Connection():
|
||||||
if self._thread and self._thread != threading.current_thread():
|
if self._thread and self._thread != threading.current_thread():
|
||||||
self._thread.join()
|
self._thread.join()
|
||||||
|
|
||||||
|
def switch_to(self, new_room):
|
||||||
|
"""
|
||||||
|
switch_to(new_room) -> bool
|
||||||
|
|
||||||
|
Returns True on success, False on failure.
|
||||||
|
|
||||||
|
Attempts to connect to new_room.
|
||||||
|
"""
|
||||||
|
|
||||||
|
old_room = self.room
|
||||||
|
logger.info("Switching to &{} from &{}".format(old_room, new_room))
|
||||||
|
self.room = new_room
|
||||||
|
self.disconnect()
|
||||||
|
|
||||||
|
if not self._connect(tries=1):
|
||||||
|
logger.info("Could not connect to &{}: Connecting to ${} again.".format(new_room, old_room))
|
||||||
|
self.room = old_room
|
||||||
|
self._connect()
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def next_id(self):
|
def next_id(self):
|
||||||
"""
|
"""
|
||||||
next_id() -> id
|
next_id() -> id
|
||||||
|
|
@ -184,22 +224,20 @@ class Connection():
|
||||||
Handle incoming packets
|
Handle incoming packets
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if "data" in packet:
|
ptype = packet.get("type")
|
||||||
data = packet["data"]
|
logger.debug("Handling packet of type {}.".format(ptype))
|
||||||
else:
|
|
||||||
data = None
|
|
||||||
|
|
||||||
if "error" in packet:
|
data = packet.get("data")
|
||||||
error = packet["error"]
|
error = packet.get("error")
|
||||||
else:
|
if error:
|
||||||
error = None
|
logger.debug("Error in packet: {!r}".format(error))
|
||||||
|
|
||||||
self._callbacks.call(packet["type"], data, error)
|
|
||||||
|
|
||||||
if "id" in packet:
|
if "id" in packet:
|
||||||
self._id_callbacks.call(packet["id"], data, error)
|
self._id_callbacks.call(packet["id"], data, error)
|
||||||
self._id_callbacks.remove(packet["id"])
|
self._id_callbacks.remove(packet["id"])
|
||||||
|
|
||||||
|
self._callbacks.call(packet["type"], data, error)
|
||||||
|
|
||||||
def _send_json(self, data):
|
def _send_json(self, data):
|
||||||
"""
|
"""
|
||||||
_send_json(data) -> None
|
_send_json(data) -> None
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue