3
0
mirror of https://github.com/jlu5/PyLink.git synced 2025-02-17 14:01:03 +01:00

relay: stop execution if spawn lock acquire fails

Also, make the lock timeout a consistent, global variable.

(partial merge of commit e24bc54bbcefc40bf73a197de2dc24f7cd42cf79)
This commit is contained in:
James Lu 2017-05-04 21:16:25 -07:00
parent fd15600d80
commit 5c7752a203

View File

@ -8,6 +8,9 @@ from pylinkirc import utils, world, conf, structures
from pylinkirc.log import log
from pylinkirc.coremods import permissions
# Sets the timeout to wait for as individual servers / the PyLink daemon to start up.
TCONDITION_TIMEOUT = 2
### GLOBAL (statekeeping) VARIABLES
relayusers = defaultdict(dict)
relayservers = defaultdict(dict)
@ -31,11 +34,11 @@ def initialize_all(irc):
# Wait for all IRC objects to be created first. This prevents
# relay servers from being spawned too early (before server authentication),
# which would break connections.
world.started.wait(2)
if world.started.wait(TCONDITION_TIMEOUT):
for chanpair, entrydata in db.items():
# Iterate over all the channels stored in our relay links DB.
network, channel = chanpair
# Initialize each relay channel on their home network, and on every linked one too.
initialize_channel(irc, channel)
for link in entrydata['links']:
@ -209,7 +212,7 @@ def get_prefix_modes(irc, remoteirc, channel, user, mlist=None):
return modes
def spawn_relay_server(irc, remoteirc):
irc.connected.wait(5)
if irc.connected.wait(TCONDITION_TIMEOUT):
try:
# ENDBURST is delayed by 3 secs on supported IRCds to prevent
# triggering join-flood protection and the like.
@ -233,13 +236,16 @@ def spawn_relay_server(irc, remoteirc):
relayservers[irc.name][remoteirc.name] = sid
return sid
else:
log.debug('(%s) skipping spawn_relay_server(%s, %s); the remote is not ready yet',
irc.name, irc.name, remoteirc.name)
def get_remote_sid(irc, remoteirc, spawn_if_missing=True):
"""Gets the remote server SID representing remoteirc on irc, spawning
it if it doesn't exist (and spawn_if_missing is enabled)."""
log.debug('(%s) Grabbing spawnlocks_servers[%s]', irc.name, irc.name)
if spawnlocks_servers[irc.name].acquire(5):
if spawnlocks_servers[irc.name].acquire(timeout=TCONDITION_TIMEOUT):
try:
sid = relayservers[irc.name][remoteirc.name]
except KeyError:
@ -343,15 +349,14 @@ def get_remote_user(irc, remoteirc, user, spawn_if_missing=True, times_tagged=0)
spawning one if it doesn't exist and spawn_if_missing is True."""
# Wait until the network is working before trying to spawn anything.
irc.connected.wait(5)
if irc.connected.wait(TCONDITION_TIMEOUT):
# Don't spawn clones for registered service bots.
sbot = irc.getServiceBot(user)
if sbot:
return sbot.uids.get(remoteirc.name)
log.debug('(%s) Grabbing spawnlocks[%s]', irc.name, irc.name)
if spawnlocks[irc.name].acquire(5):
if spawnlocks[irc.name].acquire(timeout=TCONDITION_TIMEOUT):
# Be sort-of thread safe: lock the user spawns for the current net first.
u = None
try:
@ -373,6 +378,9 @@ def get_remote_user(irc, remoteirc, user, spawn_if_missing=True, times_tagged=0)
spawnlocks[irc.name].release()
return u
else:
log.debug('(%s) skipping spawn_relay_user(%s, %s, %s, ...); the remote is not ready yet',
irc.name, irc.name, remoteirc.name, user)
def get_orig_user(irc, user, targetirc=None):
"""
@ -937,7 +945,7 @@ def handle_quit(irc, numeric, command, args):
# Lock the user spawning mechanism before proceeding, since we're going to be
# deleting client from the relayusers cache.
log.debug('(%s) Grabbing spawnlocks[%s]', irc.name, irc.name)
if spawnlocks[irc.name].acquire(5):
if spawnlocks[irc.name].acquire(timeout=TCONDITION_TIMEOUT):
for netname, user in relayusers[(irc.name, numeric)].copy().items():
remoteirc = world.networkobjects[netname]
try: # Try to quit the client. If this fails because they're missing, bail.
@ -1468,7 +1476,7 @@ def handle_disconnect(irc, numeric, command, args):
# Quit all of our users' representations on other nets, and remove
# them from our relay clients index.
log.debug('(%s) Grabbing spawnlocks[%s]', irc.name, irc.name)
if spawnlocks[irc.name].acquire(5):
if spawnlocks[irc.name].acquire(timeout=TCONDITION_TIMEOUT):
for k, v in relayusers.copy().items():
if irc.name in v:
del relayusers[k][irc.name]
@ -1479,7 +1487,7 @@ def handle_disconnect(irc, numeric, command, args):
# SQUIT all relay pseudoservers spawned for us, and remove them
# from our relay subservers index.
log.debug('(%s) Grabbing spawnlocks_servers[%s]', irc.name, irc.name)
if spawnlocks_servers[irc.name].acquire(5):
if spawnlocks_servers[irc.name].acquire(timeout=TCONDITION_TIMEOUT):
for name, ircobj in world.networkobjects.copy().items():
if name != irc.name:
try:
@ -1855,7 +1863,6 @@ def linked(irc, source, args):
# Sort the list of shared channels when displaying
for k, v in sorted(db.items()):
# Skip if we're filtering by network and the network given isn't relayed
# to the channel.
if net and not (net == k[0] or net in [link[0] for link in v['links']]):