Add hotswap server reload

This commit is contained in:
Némunaire 2012-06-23 13:38:34 +02:00
parent 9b8e1351c5
commit 7a91c49acf
2 changed files with 80 additions and 32 deletions

View File

@ -275,6 +275,22 @@ def connect(cmds, servers):
else: else:
print (" Please SELECT a server or give its name in argument.") print (" Please SELECT a server or give its name in argument.")
def hotswap(cmds, servers):
"""Reload a server class"""
global MODS, selectedServer
if len(cmds) > 1:
print ("hotswap: apply only on selected server")
elif selectedServer is not None:
del servers[selectedServer.id]
srv = server.Server(selectedServer.node, selectedServer.nick, selectedServer.owner, selectedServer.realname, selectedServer.s)
srv.update_mods(MODS)
servers[srv.id] = srv
selectedServer.kill()
selectedServer = srv
selectedServer.start()
else:
print (" Please SELECT a server or give its name in argument.")
def join(cmds, servers): def join(cmds, servers):
"""Join or leave a channel""" """Join or leave a channel"""
rd = 1 rd = 1
@ -382,6 +398,7 @@ CAPS = {
'exit': end, #Alias for quit 'exit': end, #Alias for quit
'reset': end, #Reload the prompt 'reset': end, #Reload the prompt
'load': load, #Load a servers or module configuration file 'load': load, #Load a servers or module configuration file
'hotswap': hotswap, #Reload the server class without closing the socket
'close': close, #Disconnect and remove a server from the list 'close': close, #Disconnect and remove a server from the list
'unload': unload, #Unload a module and remove it from the list 'unload': unload, #Unload a module and remove it from the list
'select': select, #Select a server 'select': select, #Select a server

View File

@ -9,36 +9,52 @@ message = __import__("message")
imp.reload(message) imp.reload(message)
class Server(threading.Thread): class Server(threading.Thread):
def __init__(self, server, nick, owner, realname): def __init__(self, node, nick, owner, realname, socket = None):
self.stop = False self.stop = False
self.stopping = threading.Event() self.stopping = threading.Event()
self.connected = False
self.nick = nick self.nick = nick
self.owner = owner self.owner = owner
self.realname = realname self.realname = realname
self.s = socket
if server.hasAttribute("server"): self.connected = self.s is not None
self.host = server.getAttribute("server") self.node = node
else:
self.host = "localhost"
if server.hasAttribute("port"):
self.port = int(server.getAttribute("port"))
else:
self.port = 6667
if server.hasAttribute("password"):
self.password = server.getAttribute("password")
else:
self.password = None
self.listen_nick = True self.listen_nick = True
self.partner = "nbr23"
self.channels = list() self.channels = list()
for channel in server.getChilds(): for channel in node.getNodes("channel"):
self.channels.append(channel.getAttribute("name")) self.channels.append(channel.getAttribute("name"))
threading.Thread.__init__(self) threading.Thread.__init__(self)
@property
def host(self):
if self.node.hasAttribute("server"):
return self.node["server"]
else:
return "localhost"
@property
def port(self):
if self.node.hasAttribute("port"):
return self.node.getInt("port")
else:
return "6667"
@property
def password(self):
if self.node.hasAttribute("password"):
return self.node["password"]
else:
return None
@property
def partner(self):
if self.node.hasAttribute("partner"):
return self.node["partner"]
else:
return None
@property @property
def id(self): def id(self):
return self.host + ":" + str(self.port) return self.host + ":" + str(self.port)
@ -50,6 +66,8 @@ class Server(threading.Thread):
self.s.send ((":%s %s %s :%s%s" % (me, cmd, to, line, endl)).encode ()) self.s.send ((":%s %s %s :%s%s" % (me, cmd, to, line, endl)).encode ())
def send_msg_final(self, channel, msg, cmd = "PRIVMSG", endl = "\r\n"): def send_msg_final(self, channel, msg, cmd = "PRIVMSG", endl = "\r\n"):
if channel == self.nick:
print ("\033[1;35mWarning:\033[0m Nemubot talks to himself: %s" % msg)
if msg is not None and channel is not None: if msg is not None and channel is not None:
for line in msg.split("\n"): for line in msg.split("\n"):
if line != "": if line != "":
@ -86,6 +104,17 @@ class Server(threading.Thread):
else: else:
return False return False
def kill(self):
if self.connected:
self.stop = True
self.connected = False
#Send a message in order to close the socket
self.s.send(("WHO %s\r\n" % self.nick).encode ())
self.stopping.wait()
return True
else:
return False
def join(self, channel): def join(self, channel):
if channel is not None and self.connected: if channel is not None and self.connected:
self.channels.append(channel) self.channels.append(channel)
@ -114,6 +143,7 @@ class Server(threading.Thread):
print (" Already connected.") print (" Already connected.")
def run(self): def run(self):
if not self.connected:
self.s = socket.socket() #Create the socket self.s = socket.socket() #Create the socket
self.s.connect((self.host, self.port)) #Connect to server self.s.connect((self.host, self.port)) #Connect to server
self.stopping.clear() self.stopping.clear()
@ -154,6 +184,7 @@ class Server(threading.Thread):
print ("\033[1;31mERROR:\033[0m occurred during the processing of the message: %s"%line) print ("\033[1;31mERROR:\033[0m occurred during the processing of the message: %s"%line)
exc_type, exc_value, exc_traceback = sys.exc_info() exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_exception(exc_type, exc_value, exc_traceback) traceback.print_exception(exc_type, exc_value, exc_traceback)
if self.connected:
self.s.close() self.s.close()
self.connected = False self.connected = False
print ("Server `%s' successfully stopped." % self.id) print ("Server `%s' successfully stopped." % self.id)