6 from sfa.util.sfalogging import logger
9 Callids: a simple mechanism to remember the call ids served so fas
10 memory-only for now - thread-safe
11 implemented as a (singleton) hash 'callid'->timestamp
16 class _call_ids_impl (dict):
19 # 5 minutes sounds amply enough
21 # when trying to get a lock
27 self._lock=threading.Lock()
30 # return True if the callid is unknown, False otherwise
31 def already_handled (self,call_id):
32 # if not provided in the call...
33 if not call_id: return False
35 for attempt in range(_call_ids_impl.retries):
36 if debug: logger.debug("Waiting for lock (%d)"%attempt)
37 if self._lock.acquire(False):
39 if debug: logger.debug("got lock (%d)"%attempt)
41 time.sleep(float(_call_ids_impl.wait_ms)/1000)
42 # in the unlikely event where we can't get the lock
44 logger.warning("_call_ids_impl.should_handle_call_id: could not acquire lock")
47 if self.has_key(call_id):
51 self[call_id]=time.time()
54 if debug: logger.debug("released lock")
60 for (k,v) in self.iteritems():
61 if (now-v) >= _call_ids_impl.purge_timeout: o_keys.append(k)
63 if debug: logger.debug("Purging call_id %r (%s)"%(k,time.strftime("%H:%M:%S",time.localtime(self[k]))))
66 logger.debug("AFTER PURGE")
67 for (k,v) in self.iteritems(): logger.debug("%s -> %s"%(k,time.strftime("%H:%M:%S",time.localtime(v))))
70 if not _call_ids_impl._instance:
71 _call_ids_impl._instance = _call_ids_impl()
72 return _call_ids_impl._instance