mirror of
https://github.com/jlu5/PyLink.git
synced 2025-02-17 14:01:03 +01:00
relay: code cleanup, possibly fix clones for PyLink clients being spawned from rare race conditions
This commit is contained in:
parent
ab5624343b
commit
54987fde4e
@ -328,30 +328,41 @@ def spawnRelayUser(irc, remoteirc, user):
|
|||||||
return u
|
return u
|
||||||
|
|
||||||
def getRemoteUser(irc, remoteirc, user, spawnIfMissing=True):
|
def getRemoteUser(irc, remoteirc, user, spawnIfMissing=True):
|
||||||
"""Gets the UID of the relay client for the given IRC network/user pair,
|
"""
|
||||||
|
Gets the UID of the relay client requested on the target network (remoteirc),
|
||||||
spawning one if it doesn't exist and spawnIfMissing is True."""
|
spawning one if it doesn't exist and spawnIfMissing is True."""
|
||||||
|
|
||||||
|
# Wait until both the local and remote networks are working before trying to spawn anything.
|
||||||
log.debug('(%s) getRemoteUser: waiting for irc.connected', irc.name)
|
log.debug('(%s) getRemoteUser: waiting for irc.connected', irc.name)
|
||||||
irc.connected.wait()
|
irc.connected.wait()
|
||||||
log.debug('(%s) getRemoteUser: waiting for %s.connected', irc.name, remoteirc.name)
|
log.debug('(%s) getRemoteUser: waiting for %s.connected', irc.name, remoteirc.name)
|
||||||
remoteirc.connected.wait()
|
remoteirc.connected.wait()
|
||||||
|
|
||||||
# If the user (stored here as {('netname', 'UID'):
|
|
||||||
# {'network1': 'UID1', 'network2': 'UID2'}}) exists, don't spawn it
|
|
||||||
# again!
|
|
||||||
try:
|
try:
|
||||||
|
# We're relaying a message from the main PyLink client. These don't have
|
||||||
|
# relay clones, so relay them through the other network's main client.
|
||||||
if user == irc.pseudoclient.uid:
|
if user == irc.pseudoclient.uid:
|
||||||
return remoteirc.pseudoclient.uid
|
return remoteirc.pseudoclient.uid
|
||||||
|
|
||||||
except AttributeError: # Network hasn't been initialized yet?
|
except AttributeError: # Network hasn't been initialized yet?
|
||||||
pass
|
return
|
||||||
|
|
||||||
with spawnlocks[irc.name]:
|
with spawnlocks[irc.name]:
|
||||||
|
# Be sort-of thread safe: lock the user spawns for the current net first.
|
||||||
u = None
|
u = None
|
||||||
try:
|
try:
|
||||||
|
# Look up the existing user, stored here as dict entries in the format:
|
||||||
|
# {('ournet', 'UID'): {'remotenet1': 'UID1', 'remotenet2': 'UID2'}}
|
||||||
u = relayusers[(irc.name, user)][remoteirc.name]
|
u = relayusers[(irc.name, user)][remoteirc.name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
# User doesn't exist. Spawn a new one if requested.
|
||||||
if spawnIfMissing:
|
if spawnIfMissing:
|
||||||
u = spawnRelayUser(irc, remoteirc, user)
|
u = spawnRelayUser(irc, remoteirc, user)
|
||||||
|
|
||||||
|
# This is a sanity check to make sure netsplits and other state resets
|
||||||
|
# don't break the relayer. If it turns out there was a client in our relayusers
|
||||||
|
# cache for the requested UID, but it doesn't match the request,
|
||||||
|
# assume it was a leftover from the last split and replace it with a new one.
|
||||||
if u and ((u not in remoteirc.users) or remoteirc.users[u].remote != (irc.name, user)):
|
if u and ((u not in remoteirc.users) or remoteirc.users[u].remote != (irc.name, user)):
|
||||||
spawnRelayUser(irc, remoteirc, user)
|
spawnRelayUser(irc, remoteirc, user)
|
||||||
return u
|
return u
|
||||||
|
Loading…
x
Reference in New Issue
Block a user