'Notify all interested observers about an event with threads from the pool'

def notify(self, subject, changeType, obj_id, *args):

    tasks = []
    assert (subject in self.SUBJECTS), ('Subject    %s    not    in    SUBJECTS' % subject)
    args = ([subject, changeType, obj_id] + list(args))
    self.observerLock.acquire()
    for (ofunc, osubject, ochangeTypes, oid, cache) in self.observers:
        try:
            if ((subject == osubject) and (changeType in ochangeTypes) and ((oid is None) or (oid == obj_id))):
                if (not cache):
                    tasks.append(ofunc)
                else:
                    if (ofunc not in self.observerscache):
                        def doQueue(ofunc):
                            self.observerLock.acquire()
                            if (ofunc in self.observerscache):
                                events = self.observerscache[ofunc]
                                del self.observerscache[ofunc]
                                del self.observertimers[ofunc]
                            else:
                                events = []
                            self.observerLock.release()
                            if events:
                                ofunc(events)
                        t = threading.Timer(cache, doQueue, (ofunc,))
                        t.setName(('Notifier-timer-%s' % subject))
                        t.start()
                        self.observerscache[ofunc] = []
                        self.observertimers[ofunc] = t
                    self.observerscache[ofunc].append(args)
        except:
            self._logger.exception('OIDs    were    %s    %s', repr(oid), repr(obj_id))
    self.observerLock.release()
    for task in tasks:
        task(*args)
