def __init__(self, server, limit = None): """ @type server: L{server.Server} @param server: Server this pool belongs to. @type limit: C{int} @param limit: Maximal number of running threads. Default is C{None} which means "no limit". """ super(ThreadPool, self).__init__() self.limit = limit self.server = server self.lock = hlib.locks.RLock(name = 'ThreadPool lock') self.worker_index = 0 self.current_count = 0 self.free_count = 0 self.queue = Queue.Queue() self.threads = {} self.hooks = {} self.stats_name = 'Pool (%s)' % self.server.name STATS.set(self.stats_name, OrderedDict([ ('Queue size', lambda s: self.queue.qsize()), ('Current threads', lambda s: self.current_count), ('Free threads', lambda s: self.free_count), ('Total threads started', 0), ('Total threads finished', 0), ('Threads', {}) ]))
def __init__(self, name, address, **kwargs): super(DB, self).__init__() self.name = name self.address = address self.db = None self.root = None self.log_transaction_handler = self.__nolog_transaction self.log_transaction_lock = hlib.locks.RLock(name = 'Transaction logging setup') self.kwargs = kwargs self.stats_name = 'Database (%s)' % self.name # pylint: disable-msg=W0621 STATS.set(self.stats_name, OrderedDict([ ('Loads', 0), ('Stores', 0), ('Commits', 0), ('Rollbacks', 0), ('Failed commits', 0), ('Connections', {}), ('Caches', {}) ])) import events events.Hook('engine.ThreadFinished', self.on_thread_finished) events.Hook('engine.RequestFinished', self.on_request_finished)
def update_stats(self): data = self.db.getActivityMonitor().getActivityAnalysis(divisions = 1)[0] connections = {} caches = {} i = 0 for data in self.db.connectionDebugInfo(): connections[i] = { 'Opened': data['opened'], 'Info': data['info'], 'Before': data['before'] } i += 1 for data in self.db.cacheDetailSize(): caches[data['connection']] = { 'Connection': data['connection'], 'Non-ghost size': data['ngsize'], 'Size': data['size'] } STATS.set(self.stats_name, 'Load', data['loads'] if 'loads' in data else 0) STATS.set(self.stats_name, 'Stores', data['stores'] if 'stores' in data else 0) STATS.set(self.stats_name, 'Connections', connections) STATS.set(self.stats_name, 'Caches', caches)
def __init__(self, app, *args, **kwargs): UserDict.__init__(self, *args, **kwargs) self.app = app self.lock = hlib.locks.RLock(name="Session storage") self.sessions = {} self.__online = None self.__online_ctime = 0 self.stats_name = "Sessions (%s)" % self.app.name STATS.set(self.stats_name, OrderedDict([("Active", lambda s: ", ".join(self.online_users))]))
def on_thread_start(self, _): # Setup hruntime info, and set stats record hruntime.service_engine = self.server.engine hruntime.service_server = self.server hruntime.service_thread = threading.current_thread() hruntime.tid = hruntime.service_thread.name STATS.set(self.stats_name, 'Threads', hruntime.tid, OrderedDict([ ('Start time', time.time()), ('Uptime', lambda s: time.time() - s['Start time']), ('Time per request', lambda s: (float(s['Total time']) / float(s['Total requests'])) if s['Total requests'] > 0 else 0.0) ])) with STATS: STATS.inc(self.stats_name, 'Total threads started')
def on_request_connected(self, _): hruntime.clean() hruntime.db.start_transaction() hruntime.dont_commit = True with STATS: STATS.inc(self.stats_name, 'Total requests') STATS.set(self.stats_name, 'Requests', hruntime.tid, OrderedDict([ ('Bytes read', 0), ('Bytes written', 0), ('Client', hlib.server.ips_to_str(hruntime.request.ips)), ('Start time', hruntime.time), ('Requested line', None), ('User', None) ]))
def __init__(self, name, app): super(Cache, self).__init__() self.name = name self.app = app self.lock = hlib.locks.RLock(name = 'Cache') self.objects = {} self.stats_name = 'Cache (%s - %s)' % (self.app.name, self.name) STATS.set(self.stats_name, OrderedDict([ ('Total objects', lambda s: sum([len(chain) for chain in self.objects.values()])), ('Total chains', lambda s: len(self.objects)), ('Total size', lambda s: sum([sum([sys.getsizeof(v) for v in chain.values()]) for chain in self.objects.values()])), ('Hits', 0), ('Misses', 0), ('Inserts', 0), ('Chains', lambda s: self.to_stats()) ]))
def test_sanity(self): with STATS: STATS.set('key1', { 'foo': 1, 'bar': 2, 'baz': { 'key1_foo': 7 } }) EQ(STATS.get('key1', 'foo'), 1) EQ(STATS.get('key1', 'bar'), 2) EQ(STATS.get('key1', 'baz', 'key1_foo'), 7) STATS.inc('key1', 'foo') STATS.add('key1', 'bar', 2) STATS.inc('key1', 'baz', 'key1_foo') EQ(STATS.get('key1', 'foo'), 2) EQ(STATS.get('key1', 'bar'), 4) EQ(STATS.get('key1', 'baz', 'key1_foo'), 8)
with self._lock: super(TournamentLists, self).created(t) hruntime.dbroot.tournaments.push(t) return True _tournament_lists = TournamentLists() f_active = _tournament_lists.f_active f_inactive = _tournament_lists.f_inactive f_archived = _tournament_lists.f_archived from hlib.stats import stats as STATS STATS.set('Tournaments lists', OrderedDict([ ('Active', lambda s: dict([ (k.name, dict(tournaments = ', '.join([str(i) for i in v]))) for k, v in _tournament_lists.snapshot('active').items() ])), ('Inactive', lambda s: dict([ (k.name, dict(tournaments = ', '.join([str(i) for i in v]))) for k, v in _tournament_lists.snapshot('inactive').items() ])), ('Archived', lambda s: dict([ (k.name, dict(tournaments = ', '.join([str(i) for i in v]))) for k, v in _tournament_lists.snapshot('archived').items() ])) ])) class TournamentCreationFlags(games.GameCreationFlags): FLAGS = ['name', 'desc', 'kind', 'owner', 'engine', 'password', 'num_players', 'limit_rounds'] MAX_OPPONENTS = 48 class Player(lib.play.Player): def __init__(self, tournament, user): lib.play.Player.__init__(self, user) self.tournament = tournament self.active = True self.points = 0
def on_request_started(self, _): """ Default hlib handler for C{engine.RequestStarted} event. Prepare enviroment for (and based on) new request. Reset L{hruntime} properties to default values, start new db transaction, and check basic access controls for new request. @raise http.Prohibited: Raised when requested resource is marked as prohibited (using L{handlers.prohibited}) @raise http.Redirect: Raised when requested resource is admin-access only (using L{handlers.require_admin}). Also can be raised by internal call to L{auth.check_session}. """ req = hruntime.request if req.requires_write != True: hruntime.db.doom() if req.requires_hosts: hosts_allowed = req.requires_hosts() hosts_present = req.ips def __check_host(h): for host_allowed in hosts_allowed: if type(host_allowed) in (ipaddr.IPv4Address, ipaddr.IPv6Address) and h == host_allowed: return True if type(host_allowed) in (ipaddr.IPv4Network, ipaddr.IPv6Network) and h in host_allowed: return True return False if len(hosts_present) <= 0: # handler has require_hosts but client present no address => fail passed = False elif len(hosts_present) == 1: passed = __check_host(hosts_present[0]) elif len(hosts_present) > 1: passed = __check_host(hosts_present[1]) if passed != True: hruntime.db.doom() raise hlib.http.Prohibited() if req.requires_login: io_regime = hlib.handlers.tag_fn_check(req.handler, 'ioregime', None) if not io_regime: hruntime.db.doom() raise hlib.http.Prohibited() io_regime.check_session() hruntime.db.log_transaction('user-assigned') STATS.set(self.stats_name, 'Requests', hruntime.tid, 'User', hruntime.user.name) if req.is_prohibited: hruntime.db.doom() raise hlib.http.Prohibited() if hruntime.dbroot.server.maintenance_mode == True and req.requires_login and hruntime.user.maintenance_access != True: hruntime.db.doom() raise hlib.http.Redirect('/maintenance/') if req.requires_admin and not hruntime.user.is_admin: hruntime.db.doom() raise hlib.http.Redirect('/admin/') hruntime.dont_commit = False
def on_request_accepted(self, _): STATS.set(self.stats_name, 'Requests', hruntime.tid, 'Client', hlib.server.ips_to_str(hruntime.request.ips)) STATS.set(self.stats_name, 'Requests', hruntime.tid, 'Requested', hruntime.request.requested_line) hruntime.db.log_transaction('requested-set', requested = hruntime.request.requested)
def __init__(self, name, server_configs): super(Engine, self).__init__() self.name = name self.quit_event = threading.Event() self.servers = [] self.apps = {} self.hooks = {} self.scheduler = hlib.scheduler.SchedulerThread(self) self.scheduler.start() self.scheduler.add_task(DataBaseGCTask(), None) self.scheduler.add_task(PurgeSessionsTask(), None) self.scheduler.add_task(SaveSessionsTask(), None) i = 0 for sc in server_configs: self.apps[sc['app'].name] = sc['app'] sc['app'].engines.append(self) server = hlib.server.Server(self, 'server-%i' % i, sc) self.servers.append(server) i += 1 self.stats_name = self.name STATS.set(self.stats_name, OrderedDict([ ('Current time', lambda s: hruntime.time), ('Current requests', lambda s: len(s['Requests'])), ('Start time', time.time()), ('Uptime', lambda s: time.time() - s['Start time']), ('Total bytes read', 0), ('Total bytes written', 0), ('Total requests', 0), ('Total time', 0), ('Bytes read/second', lambda s: s['Total bytes read'] / s['Uptime'](s)), ('Bytes written/second', lambda s: s['Total bytes written'] / s['Uptime'](s)), ('Bytes read/request', lambda s: (s['Total requests'] and (s['Total bytes read'] / float(s['Total requests'])) or 0.0)), ('Bytes written/request', lambda s: (s['Total requests'] and (s['Total bytes written'] / float(s['Total requests'])) or 0.0)), ('Requests/second', lambda s: float(s['Total requests']) / s['Uptime'](s)), ('Requests', {}), ('Missing handlers', 0), ('RO requests', 0), ('Forced RO requests', 0), ('Failed commits', 0), ])) self.console = hlib.console.Console('main console', self, sys.stdin, sys.stdout) self.console.register_command('db', hlib.database.Command_Database) self.console.register_command('server', hlib.server.Command_Server) self.console.register_command('engine', Command_Engine, self) with ENGINES_LOCK: ENGINES.append(self)