Fixed bug #1019387. Again.

This commit is contained in:
Jeremy Fincher 2004-09-14 17:12:21 +00:00
parent 934363db10
commit e44f7ab50c
3 changed files with 37 additions and 28 deletions

View File

@ -533,7 +533,13 @@ class FloodQueue(object):
return self.queues[key] return self.queues[key]
except KeyError: except KeyError:
if insert: if insert:
q = structures.TimeoutQueue(self.getTimeout) # python--
# instancemethod.__repr__ calls the instance.__repr__, which
# means that our __repr__ calls self.queues.__repr__, which
# calls structures.TimeoutQueue.__repr__, which calls
# getTimeout.__repr__, which calls our __repr__, which calls...
getTimeout = lambda : self.getTimeout()
q = structures.TimeoutQueue(getTimeout)
self.queues[key] = q self.queues[key] = q
return q return q
else: else:

View File

@ -159,51 +159,50 @@ class UrlSnarfThread(threading.Thread):
threading.Thread.__init__(self, *args, **kwargs) threading.Thread.__init__(self, *args, **kwargs)
self.setDaemon(True) self.setDaemon(True)
def run(self):
try:
super(UrlSnarfThread, self).run()
finally:
# This was acquired in newf in urlSnarfer.
_snarfLock.release()
class SnarfQueue(ircutils.FloodQueue): class SnarfQueue(ircutils.FloodQueue):
timeout = conf.supybot.snarfThrottle
def key(self, channel): def key(self, channel):
return channel return channel
def getTimeout(self):
return conf.supybot.snarfThrottle()
_snarfed = SnarfQueue() _snarfed = SnarfQueue()
class SnarfIrc(object): _snarfLock = threading.Lock()
def __init__(self, irc, channel, url):
self.irc = irc
self.url = url
self.channel = channel
def reply(self, *args, **kwargs):
_snarfed.enqueue(self.channel, self.url)
self.irc.reply(*args, **kwargs)
def __getattr__(self, attr):
return getattr(self.irc, attr)
def urlSnarfer(f): def urlSnarfer(f):
"""Protects the snarfer from loops and whatnot.""" """Protects the snarfer from loops and whatnot."""
def newf(self, irc, msg, match, *L, **kwargs): def newf(self, irc, msg, match, *L, **kwargs):
if msg.repliedTo: _snarfLock.acquire()
self.log.debug('Not calling snarfer, msg is already repliedTo.') url = match.group(0)
return
channel = msg.args[0] channel = msg.args[0]
if not ircutils.isChannel(channel): if not ircutils.isChannel(channel):
return return
c = ircdb.channels.getChannel(channel) if ircdb.channels.getChannel(channel).lobotomized:
if c.lobotomized: self.log.info('Not snarfing in %s: lobotomized.', channel)
self.log.info('Refusing to snarf in %s: lobotomized.', channel)
return return
url = match.group(0)
if _snarfed.has(channel, url): if _snarfed.has(channel, url):
self.log.info('Refusing to snarf %s, already snarfed.', url) self.log.info('Throttling snarf of %s in %s.', url, channel)
return return
irc = SnarfIrc(irc, channel, url) _snarfed.enqueue(channel, url)
def doSnarf():
try:
if msg.repliedTo:
self.log.debug('Not snarfing, msg is already repliedTo.')
return
f(self, irc, msg, match, *L, **kwargs)
finally:
_snarfLock.release()
if threading.currentThread() is not world.mainThread: if threading.currentThread() is not world.mainThread:
f(self, irc, msg, match, *L, **kwargs) doSnarf()
else: else:
L = list(L) L = list(L)
t = UrlSnarfThread(target=f,args=[self,irc,msg,match]+L,url=url) t = UrlSnarfThread(target=doSnarf, url=url)
t.start() t.start()
newf = utils.changeFunctionName(newf, f.func_name, f.__doc__) newf = utils.changeFunctionName(newf, f.func_name, f.__doc__)
return newf return newf

View File

@ -311,6 +311,10 @@ class TimeoutQueue(object):
self.queue = queue self.queue = queue
self.timeout = timeout self.timeout = timeout
def __repr__(self):
return '%s(timeout=%r, queue=%r)' % (self.__class__.__name__,
self.timeout, self.queue)
def _getTimeout(self): def _getTimeout(self):
if callable(self.timeout): if callable(self.timeout):
return self.timeout() return self.timeout()