96 lines
2.3 KiB
Python
96 lines
2.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
# vi:si:et:sw=4:sts=4:ts=4
|
|
|
|
|
|
from threading import Thread
|
|
from queue import Queue
|
|
|
|
from tornado.ioloop import PeriodicCallback
|
|
|
|
from . import directory
|
|
from .localnodes import LocalNodes
|
|
from .link import can_connect, node_url
|
|
|
|
import logging
|
|
logger = logging.getLogger('lookup')
|
|
|
|
|
|
class Nodes(Thread):
|
|
|
|
_active = True
|
|
_local = None
|
|
_nodes = {}
|
|
|
|
def __init__(self):
|
|
self._local = LocalNodes()
|
|
Thread.__init__(self)
|
|
self._q = Queue()
|
|
self.daemon = True
|
|
self._cleanup = PeriodicCallback(lambda: self._q.put(''), 120000)
|
|
self._cleanup.start()
|
|
self.start()
|
|
|
|
def cleanup(self):
|
|
if self._active:
|
|
self._local.cleanup()
|
|
for id in list(self._nodes.keys()):
|
|
if id in self._local._nodes:
|
|
del self._nodes[id]
|
|
if not can_connect(self._nodes[id]):
|
|
del self._nodes[id]
|
|
if not self._active:
|
|
break
|
|
|
|
def fingerprint(self, id):
|
|
node = self.get(id)
|
|
if node:
|
|
return node['cert']
|
|
return None
|
|
|
|
def get(self, id):
|
|
# check local nodes
|
|
node = self._local.get(id)
|
|
if not node:
|
|
# check local cache
|
|
node = self._nodes.get(id)
|
|
# lookup directory
|
|
if not node:
|
|
try:
|
|
node = directory.get(id)
|
|
except:
|
|
logger.debug('directory failed', exc_info=1)
|
|
node = None
|
|
if node:
|
|
self._nodes[id] = node
|
|
if node:
|
|
node['url'] = node_url(node)
|
|
return node
|
|
|
|
def info(self):
|
|
l = self._local.info()
|
|
return {
|
|
'local': l,
|
|
'nodes': sorted(set(list(self._nodes.keys()) + l))
|
|
}
|
|
|
|
def join(self):
|
|
self._active = False
|
|
self._q.put('')
|
|
self._local.join()
|
|
return Thread.join(self)
|
|
|
|
def run(self):
|
|
while self._active:
|
|
self._q.get()
|
|
if self._active:
|
|
self.cleanup()
|
|
|
|
def url(self, user_id):
|
|
node = self.get(user_id)
|
|
if node:
|
|
url = node['url']
|
|
else:
|
|
url = None
|
|
logger.debug('resolved %s -> %s', user_id, url)
|
|
return url
|