mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-30 23:09:23 +01:00
Doesn't quite work yet; still blocks everything on disconnect for some reason...
This commit is contained in:
parent
0aa2f98705
commit
9bef93c341
29
main.py
29
main.py
@ -46,13 +46,20 @@ class Irc():
|
|||||||
# is also dependent on the protocol module.
|
# is also dependent on the protocol module.
|
||||||
self.maxnicklen = 30
|
self.maxnicklen = 30
|
||||||
self.prefixmodes = 'ov'
|
self.prefixmodes = 'ov'
|
||||||
|
# Uplink SID (filled in by protocol module)
|
||||||
|
self.uplink = None
|
||||||
|
|
||||||
self.serverdata = conf['servers'][netname]
|
self.serverdata = conf['servers'][netname]
|
||||||
self.sid = self.serverdata["sid"]
|
self.sid = self.serverdata["sid"]
|
||||||
self.botdata = conf['bot']
|
self.botdata = conf['bot']
|
||||||
self.proto = proto
|
self.proto = proto
|
||||||
|
self.pingfreq = self.serverdata.get('pingfreq') or 10
|
||||||
|
self.pingtimeout = self.pingfreq * 2
|
||||||
|
|
||||||
self.connection_thread = threading.Thread(target = self.connect)
|
self.connection_thread = threading.Thread(target = self.connect)
|
||||||
self.connection_thread.start()
|
self.connection_thread.start()
|
||||||
|
self.pingTimer = None
|
||||||
|
self.lastping = time.time()
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
ip = self.serverdata["ip"]
|
ip = self.serverdata["ip"]
|
||||||
@ -61,9 +68,9 @@ class Irc():
|
|||||||
try:
|
try:
|
||||||
# Initial connection timeout is a lot smaller than the timeout after
|
# Initial connection timeout is a lot smaller than the timeout after
|
||||||
# we've connected; this is intentional.
|
# we've connected; this is intentional.
|
||||||
self.socket = socket.create_connection((ip, port), timeout=10)
|
self.socket = socket.create_connection((ip, port), timeout=1)
|
||||||
self.socket.setblocking(0)
|
self.socket.setblocking(0)
|
||||||
self.socket.settimeout(180)
|
self.socket.settimeout(self.pingtimeout)
|
||||||
self.proto.connect(self)
|
self.proto.connect(self)
|
||||||
except (socket.error, classes.ProtocolError, ConnectionError) as e:
|
except (socket.error, classes.ProtocolError, ConnectionError) as e:
|
||||||
log.warning('(%s) Failed to connect to IRC: %s: %s',
|
log.warning('(%s) Failed to connect to IRC: %s: %s',
|
||||||
@ -71,16 +78,19 @@ class Irc():
|
|||||||
self.disconnect()
|
self.disconnect()
|
||||||
else:
|
else:
|
||||||
self.spawnMain()
|
self.spawnMain()
|
||||||
|
self.schedulePing()
|
||||||
self.run()
|
self.run()
|
||||||
|
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
|
log.debug('(%s) Canceling pingTimer at %s due to disconnect() call', self.name, time.time())
|
||||||
self.connected.clear()
|
self.connected.clear()
|
||||||
try:
|
try:
|
||||||
self.socket.close()
|
self.socket.close()
|
||||||
|
self.pingTimer.cancel()
|
||||||
except: # Socket timed out during creation; ignore
|
except: # Socket timed out during creation; ignore
|
||||||
pass
|
pass
|
||||||
autoconnect = self.serverdata.get('autoconnect')
|
autoconnect = self.serverdata.get('autoconnect')
|
||||||
if autoconnect is not None and autoconnect >= 0:
|
if autoconnect is not None and autoconnect >= 1110:
|
||||||
log.info('(%s) Going to auto-reconnect in %s seconds.', self.name, autoconnect)
|
log.info('(%s) Going to auto-reconnect in %s seconds.', self.name, autoconnect)
|
||||||
time.sleep(autoconnect)
|
time.sleep(autoconnect)
|
||||||
self.connect()
|
self.connect()
|
||||||
@ -88,7 +98,9 @@ class Irc():
|
|||||||
def run(self):
|
def run(self):
|
||||||
buf = ""
|
buf = ""
|
||||||
data = ""
|
data = ""
|
||||||
while True:
|
while (time.time() - self.lastping) < self.pingtimeout:
|
||||||
|
log.debug('(%s) time_since_last_ping: %s', self.name, (time.time() - self.lastping))
|
||||||
|
log.debug('(%s) self.pingtimeout: %s', self.name, self.pingtimeout)
|
||||||
try:
|
try:
|
||||||
data = self.socket.recv(2048).decode("utf-8")
|
data = self.socket.recv(2048).decode("utf-8")
|
||||||
buf += data
|
buf += data
|
||||||
@ -115,7 +127,14 @@ class Irc():
|
|||||||
except (socket.error, classes.ProtocolError, ConnectionError) as e:
|
except (socket.error, classes.ProtocolError, ConnectionError) as e:
|
||||||
log.warning('(%s) Disconnected from IRC: %s: %s',
|
log.warning('(%s) Disconnected from IRC: %s: %s',
|
||||||
self.name, type(e).__name__, str(e))
|
self.name, type(e).__name__, str(e))
|
||||||
self.disconnect()
|
raise ProtocolError
|
||||||
|
|
||||||
|
def schedulePing(self):
|
||||||
|
self.proto.pingServer(self)
|
||||||
|
self.pingTimer = threading.Timer(self.pingfreq, self.schedulePing)
|
||||||
|
self.pingTimer.daemon = True
|
||||||
|
self.pingTimer.start()
|
||||||
|
log.debug('(%s) Ping scheduled at %s', self.name, time.time())
|
||||||
|
|
||||||
def spawnMain(self):
|
def spawnMain(self):
|
||||||
nick = self.botdata.get('nick') or 'PyLink'
|
nick = self.botdata.get('nick') or 'PyLink'
|
||||||
|
@ -69,8 +69,10 @@ def loadDB():
|
|||||||
", creating a new one in memory...", dbname)
|
", creating a new one in memory...", dbname)
|
||||||
db = {}
|
db = {}
|
||||||
|
|
||||||
def exportDB(scheduler):
|
def exportDB():
|
||||||
scheduler.enter(30, 1, exportDB, argument=(scheduler,))
|
scheduler = utils.schedulers.get('relaydb')
|
||||||
|
if scheduler:
|
||||||
|
scheduler.enter(30, 1, exportDB)
|
||||||
log.debug("Relay: exporting links database to %s", dbname)
|
log.debug("Relay: exporting links database to %s", dbname)
|
||||||
with open(dbname, 'wb') as f:
|
with open(dbname, 'wb') as f:
|
||||||
pickle.dump(db, f, protocol=4)
|
pickle.dump(db, f, protocol=4)
|
||||||
@ -683,7 +685,7 @@ def initializeAll(irc):
|
|||||||
def main():
|
def main():
|
||||||
loadDB()
|
loadDB()
|
||||||
utils.schedulers['relaydb'] = scheduler = sched.scheduler()
|
utils.schedulers['relaydb'] = scheduler = sched.scheduler()
|
||||||
scheduler.enter(30, 1, exportDB, argument=(scheduler,))
|
scheduler.enter(30, 1, exportDB)
|
||||||
# Thread this because exportDB() queues itself as part of its
|
# Thread this because exportDB() queues itself as part of its
|
||||||
# execution, in order to get a repeating loop.
|
# execution, in order to get a repeating loop.
|
||||||
thread = threading.Thread(target=scheduler.run)
|
thread = threading.Thread(target=scheduler.run)
|
||||||
|
@ -286,6 +286,12 @@ def updateClient(irc, numeric, field, text):
|
|||||||
else:
|
else:
|
||||||
raise ValueError("Changing field %r of a client is unsupported by this protocol." % field)
|
raise ValueError("Changing field %r of a client is unsupported by this protocol." % field)
|
||||||
|
|
||||||
|
def pingServer(irc, source=None, target=None):
|
||||||
|
source = source or irc.sid
|
||||||
|
target = target or irc.uplink
|
||||||
|
if not (target is None or source is None):
|
||||||
|
_send(irc, source, 'PING %s %s' % (source, target))
|
||||||
|
|
||||||
def connect(irc):
|
def connect(irc):
|
||||||
irc.start_ts = ts = int(time.time())
|
irc.start_ts = ts = int(time.time())
|
||||||
irc.uidgen = {}
|
irc.uidgen = {}
|
||||||
@ -307,6 +313,10 @@ def handle_ping(irc, source, command, args):
|
|||||||
if utils.isInternalServer(irc, args[1]):
|
if utils.isInternalServer(irc, args[1]):
|
||||||
_send(irc, args[1], 'PONG %s %s' % (args[1], source))
|
_send(irc, args[1], 'PONG %s %s' % (args[1], source))
|
||||||
|
|
||||||
|
def handle_pong(irc, source, command, args):
|
||||||
|
if source == irc.uplink and args[1] == irc.sid:
|
||||||
|
irc.lastping = time.time()
|
||||||
|
|
||||||
def handle_privmsg(irc, source, command, args):
|
def handle_privmsg(irc, source, command, args):
|
||||||
return {'target': args[0], 'text': args[1]}
|
return {'target': args[0], 'text': args[1]}
|
||||||
|
|
||||||
@ -490,6 +500,7 @@ def handle_events(irc, data):
|
|||||||
# Check if recvpass is correct
|
# Check if recvpass is correct
|
||||||
raise ProtocolError('Error: recvpass from uplink server %s does not match configuration!' % servername)
|
raise ProtocolError('Error: recvpass from uplink server %s does not match configuration!' % servername)
|
||||||
irc.servers[numeric] = IrcServer(None, servername)
|
irc.servers[numeric] = IrcServer(None, servername)
|
||||||
|
irc.uplink = numeric
|
||||||
return
|
return
|
||||||
elif args[0] == 'CAPAB':
|
elif args[0] == 'CAPAB':
|
||||||
# Capability negotiation with our uplink
|
# Capability negotiation with our uplink
|
||||||
|
Loading…
Reference in New Issue
Block a user