Ejemplo n.º 1
0
 def __init__(self, db_queue, db_start, host, port, protocol, room):
     self.logger = logging.getLogger("webserver")
     self.logger.setLevel(LOG_LEVEL)
     self.db_queue = db_queue
     self.db_start = db_start
     # Only one thread can access a connection object 
     self.db_done = threading.Event()
     # Avoid querying the database twice in a row
     self.db_lock = threading.Lock()
     self.host = host
     self.port = port
     self.protocol = protocol
     self.room = room
     f = open(os.path.join("web","template.html"), 'r')
     self.template = SimpleTemplate(f)
     f.close()
     self.cache = None
     self.last_render = 0
Ejemplo n.º 2
0
class NaokoWebServer(object):
    dbclient = None
    def __init__(self, db_queue, db_start, host, port, protocol, room):
        self.logger = logging.getLogger("webserver")
        self.logger.setLevel(LOG_LEVEL)
        self.db_queue = db_queue
        self.db_start = db_start
        # Only one thread can access a connection object 
        self.db_done = threading.Event()
        # Avoid querying the database twice in a row
        self.db_lock = threading.Lock()
        self.host = host
        self.port = port
        self.protocol = protocol
        self.room = room
        f = open(os.path.join("web","template.html"), 'r')
        self.template = SimpleTemplate(f)
        f.close()
        self.cache = None
        self.last_render = 0

    def render(self):
        if time.time() - self.last_render > 60 * 30:
            self.db_lock.acquire()
            if time.time() - self.last_render > 60 * 30:
                self.getData()
            self.db_lock.release()
        return self.rendered

    def static(self, path):
        return static_file(path, root=os.path.join("web", "static"))

    def getData(self):
        self.logger.debug("Fetching new data from the database")
        self.db_done.clear()
        self.db_queue.append(self._getData)
        self.db_start.set()
        self.db_done.wait()
        
    # Takes 4-5 seconds to get everything
    # If performance is a problem possible solutions are:
    # 1: ajax calls + appears more responsive to the user, not just sitting on a blank page
    #       - more http requests will be extremely slow on the bottle.py http server, still puts heavy load on the sqlite database
    # 2: precalculation/running totals in the database + faster, no extra calls, extra load on the database in negligible, potentially serve new data with every request
    #       - complicates database more, requires extra tables and additional columns, initial database upgrade may take a very long time, much more difficult to change decisions later
    def _getData(self): 
        averageUsers = map(lambda (x, y): [int(x), y], NaokoWebServer.dbclient.getAverageUsers())
        userVideoStats = NaokoWebServer.dbclient.getUserVideoStats()
        userChatStats = NaokoWebServer.dbclient.getUserChatStats()
        popularVideos = NaokoWebServer.dbclient.getPopularVideos()
        # Takes 20+ seconds alone on a 100mb database, unacceptable
        #messageStats = NaokoWebServer.dbclient.getMessageCounts()
        self.rendered = self.template.render(averageUsers=averageUsers, userChatStats=userChatStats, popularVideos=popularVideos, userVideoStats=userVideoStats, room=self.room)
        self.last_render = time.time()
        self.db_done.set()    

    def start(self):
        route('/static/<path:path>')(self.static)
        route("/")(self.render)
        if self.protocol == "fastcgi":
            from flup.server.fcgi import WSGIServer
            WSGIServer(default_app(), bindAddress=(self.host, int(self.port))).run()
        elif self.protocol == "http":
            run(host=self.host, port=int(self.port))