NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

__init__.py (15082B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\bluepy\__init__.py
      2 from future.utils import raise_
      3 import atexit
      4 import blue
      5 import contextlib
      6 import re
      7 import stackless
      8 import sys
      9 import traceback
     10 import weakref
     11 import utillib as util
     12 import ccpProfile
     13 import datetime
     14 STACKLESS_TRACING_ENABLED_KEY = 'stackless_tracing_enabled'
     15 tasklet_id = 0
     16 
     17 class TaskletExt(stackless.tasklet):
     18     __slots__ = ['context',
     19      'localStorage',
     20      'storedContext',
     21      'startTime',
     22      'endTime',
     23      'runTime',
     24      'tasklet_id',
     25      'origin_traceback',
     26      'highlighted',
     27      'method_name',
     28      'module_name',
     29      'file_name',
     30      'line_number',
     31      'parent_callsite',
     32      'tracer',
     33      'trace_id',
     34      'parent_id',
     35      'sampled',
     36      'ingress_id',
     37      'sample_rate',
     38      'creation_datetime']
     39 
     40     @staticmethod
     41     def GetWrapper(method):
     42         if not callable(method):
     43             raise TypeError('TaskletExt::__new__ argument "method" must be callable.')
     44 
     45         def CallWrapper(*args, **kwds):
     46             current = stackless.getcurrent()
     47             current.startTime = blue.os.GetWallclockTimeNow()
     48             oldtimer = PushTimer(current.context)
     49             exc = None
     50             with tasklet_trace(current):
     51                 try:
     52                     try:
     53                         return method(*args, **kwds)
     54                     except TaskletExit as e:
     55                         pass
     56                     except SystemExit as e:
     57                         import logmodule as log
     58                         log.general.Log('system %s exiting with %r' % (stackless.getcurrent(), e), log.LGINFO)
     59                     except Exception:
     60                         import logmodule as log
     61                         log.LogException('Unhandled exception in %r' % stackless.getcurrent())
     62 
     63                     return
     64                 except:
     65                     traceback.print_exc()
     66                     if exc:
     67                         traceback.print_exception(exc[0], exc[1], exc[2])
     68                 finally:
     69                     exc = None
     70                     PopTimer(oldtimer)
     71                     current.endTime = blue.os.GetWallclockTimeNow()
     72 
     73         return CallWrapper
     74 
     75     def __new__(cls, ctx, method = None, stackless_tracing_enabled = True):
     76         global tasklet_id
     77         tid = tasklet_id
     78         tasklet_id += 1
     79         if method:
     80             t = stackless.tasklet.__new__(cls, cls.GetWrapper(method))
     81         else:
     82             t = stackless.tasklet.__new__(cls)
     83         t.creation_datetime = datetime.datetime.utcnow()
     84         c = stackless.getcurrent()
     85         ls = getattr(c, 'localStorage', None)
     86         if ls is None:
     87             t.localStorage = {}
     88         else:
     89             t.localStorage = dict(ls)
     90         t.storedContext = t.context = ctx
     91         t.method_name = getattr(method, '__name__', 'unknown_method')
     92         t.module_name = getattr(method, '__module__', 'unknown_module')
     93         try:
     94             t.file_name = method.__code__.co_filename
     95             t.line_number = method.__code__.co_firstlineno
     96         except AttributeError:
     97             t.file_name = 'unknown_file'
     98             t.line_number = 0
     99 
    100         parent_module_name = getattr(c, 'module_name', 'unknown_parent_module')
    101         parent_method_name = getattr(c, 'method_name', 'unknown_parent_method')
    102         t.parent_callsite = ('{}.{}'.format(parent_module_name, parent_method_name),)
    103         if stackless_tracing_enabled:
    104             cls.copy_tracer_and_state(c, t)
    105         t.runTime = 0.0
    106         t.tasklet_id = tid
    107         t.highlighted = False
    108         tasklets[t] = True
    109         return t
    110 
    111     @staticmethod
    112     def copy_tracer_and_state(old, new):
    113         trace_context_slots = ['trace_id',
    114          'parent_id',
    115          'sampled',
    116          'ingress_id',
    117          'sample_rate']
    118         for trace_slot in trace_context_slots:
    119             setattr(new, trace_slot, getattr(old, trace_slot, None))
    120 
    121         tracer = getattr(old, 'tracer', None)
    122         if tracer is not None:
    123             setattr(new, 'tracer', tracer.clone())
    124 
    125     def bind(self, callableObject):
    126         return stackless.tasklet.bind(self, self.CallWrapper(callableObject))
    127 
    128     def __repr__(self):
    129         abps = [ getattr(self, attr) for attr in ['alive',
    130          'blocked',
    131          'paused',
    132          'scheduled'] ]
    133         abps = ''.join((str(int(flag)) for flag in abps))
    134         return '<TaskletExt object at 0x%x, abps=%s, ctxt=%r>' % (id(self), abps, getattr(self, 'storedContext', None))
    135 
    136     def __reduce__(self):
    137         return (str, ("__reduce__()'d " + repr(self),))
    138 
    139     def PushTimer(self, ctxt):
    140         blue.pyos.taskletTimer.EnterTasklet(ctxt)
    141 
    142     def PopTimer(self, ctxt):
    143         blue.pyos.taskletTimer.ReturnFromTasklet(ctxt)
    144 
    145     def GetCurrent(self):
    146         blue.pyos.taskletTimer.GetCurrent()
    147 
    148     def GetWallclockTime(self):
    149         return (blue.os.GetWallclockTimeNow() - self.startTime) * 1e-07
    150 
    151     def GetRunTime(self):
    152         return self.runTime + blue.pyos.GetTimeSinceSwitch()
    153 
    154 
    155 tasklets = weakref.WeakKeyDictionary()
    156 ctxtfilter = re.compile('at 0x[0-9A-F]+')
    157 
    158 def tasklet_trace(t):
    159     tracer = getattr(t, 'tracer', None)
    160     if tracer is None:
    161         return no_tasklet_tracer()
    162     return tracer.get_tasklet_tracer(t)
    163 
    164 
    165 @contextlib.contextmanager
    166 def no_tasklet_tracer():
    167     yield
    168 
    169 
    170 def tracing_enabled(**kwargs):
    171     if STACKLESS_TRACING_ENABLED_KEY not in kwargs.keys():
    172         return (True, kwargs)
    173     stackless_tracing_enabled = kwargs[STACKLESS_TRACING_ENABLED_KEY]
    174     del kwargs[STACKLESS_TRACING_ENABLED_KEY]
    175     return (stackless_tracing_enabled, kwargs)
    176 
    177 
    178 def CreateTaskletExt(func, *args, **kw):
    179     ctx = ctxtfilter.sub('', repr(func))
    180     ctx = blue.pyos.taskletTimer.GetCurrent().split('^')[-1] + '^' + ctx
    181     stackless_tracing_enabled, kw = tracing_enabled(**kw)
    182     t = TaskletExt(ctx, func, stackless_tracing_enabled=stackless_tracing_enabled)
    183     t(*args, **kw)
    184     return t
    185 
    186 
    187 def Shutdown(exitprocs):
    188 
    189     def RunAll():
    190         stackless.getcurrent().block_trap = True
    191         for proc in exitprocs:
    192             try:
    193                 proc()
    194             except Exception:
    195                 import logmodule as log
    196                 log.LogException('exitproc ' + repr(proc), toAlertSvc=False)
    197                 sys.exc_clear()
    198 
    199     if exitprocs:
    200         TaskletExt('Shutdown', RunAll)()
    201         intr = stackless.run(1000000)
    202         if intr:
    203             log.general.Log('ExitProcs interrupted at tasklet ' + repr(intr), log.LGERR)
    204     GetTaskletDump(True)
    205     if len(tasklets):
    206         KillTasklets()
    207         GetTaskletDump(True)
    208 
    209 
    210 def GetTaskletDump(logIt = True):
    211     import logmodule as log
    212     lines = []
    213     lines.append('GetTaskletDump:  %s TaskletExt objects alive' % len(tasklets))
    214     lines.append('[context] - [code] - [stack depth] - [creation context]')
    215     for t in tasklets.keys():
    216         try:
    217             if t.frame:
    218                 stack = traceback.extract_stack(t.frame, 1)
    219                 depth = len(stack)
    220                 f = stack[-1]
    221                 code = '%s(%s)' % (f[0], f[1])
    222             else:
    223                 code, depth = ('<no frame>', 0)
    224         except Exception as e:
    225             code, depth = repr(e), 0
    226 
    227         ctx = (getattr(t, 'context', '(unknown)'),)
    228         sctx = getattr(t, 'storedContext', '(unknown)')
    229         l = '%s - %s - %s - %s' % (sctx,
    230          code,
    231          depth,
    232          ctx)
    233         lines.append(l)
    234 
    235     lines.append('End TaskletDump')
    236     if logIt:
    237         for l in lines:
    238             log.general.Log(l, log.LGINFO)
    239 
    240     return '\n'.join(lines) + '\n'
    241 
    242 
    243 def KillTasklets():
    244     t = TaskletExt('KillTasklets', KillTasklets_)
    245     t()
    246     t.run()
    247 
    248 
    249 def KillTasklets_():
    250     import logmodule as log
    251     log.general.Log('killing all %s TaskletExt objects' % len(tasklets), log.LGINFO)
    252     for i in range(3):
    253         for t in tasklets.keys():
    254             if t is stackless.getcurrent():
    255                 continue
    256             try:
    257                 if t.frame:
    258                     log.general.Log('killing %s' % t, log.LGINFO)
    259                     t.kill()
    260                 else:
    261                     log.general.Log('ignoring %r, no frame.' % t, log.LGINFO)
    262             except RuntimeError as e:
    263                 log.general.Log("couldn't kill %r: %r" % (t, e), log.LGWARN)
    264 
    265     log.general.Log('killing done', log.LGINFO)
    266 
    267 
    268 class PyResFile(object):
    269     __slots__ = ['rf',
    270      'name',
    271      'mode',
    272      'softspace']
    273 
    274     def __init__(self, path, mode = 'r', bufsize = -1):
    275         self.rf = blue.ResFile()
    276         self.mode = mode
    277         self.name = path
    278         if 'w' in mode:
    279             try:
    280                 self.rf.Create(path)
    281             except:
    282                 raise_(IOError, 'could not create ' + path)
    283 
    284         else:
    285             readonly = 'a' not in mode and '+' not in mode
    286             try:
    287                 self.rf.OpenAlways(path, readonly, mode)
    288             except:
    289                 raise_(IOError, 'could not open ' + path)
    290 
    291     def read(self, count = 0):
    292         try:
    293             return self.rf.read(count)
    294         except:
    295             raise_(IOError, 'could not read %d bytes from %s' % (count, self.rf.filename))
    296 
    297     def write(self, data):
    298         raise NotImplemented
    299 
    300     def readline(self, size = 0):
    301         raise NotImplemented
    302 
    303     def readlines(self, sizehint = 0):
    304         r = []
    305         while True:
    306             l = self.readline()
    307             if not l:
    308                 return r
    309             r.append(l)
    310 
    311     def writelines(self, iterable):
    312         for i in iterable:
    313             self.write(i)
    314 
    315     def seek(self, where, whence = 0):
    316         if whence == 1:
    317             where += self.rf.pos
    318         elif whence == 2:
    319             where += self.rf.size
    320         try:
    321             self.rf.Seek(where)
    322         except:
    323             raise_(IOError, 'could not seek to pos %d in %s' % (where, self.rf.filename))
    324 
    325     def tell(self):
    326         return self.rf.pos
    327 
    328     def truncate(self, size = None):
    329         if size is None:
    330             size = self.rf.pos
    331         try:
    332             self.rf.SetSize(size)
    333         except:
    334             raise_(IOError, 'could not trucated file %s to %d bytes' % (self.rf.filename, size))
    335 
    336     def flush():
    337         pass
    338 
    339     def isatty():
    340         return False
    341 
    342     def close(self):
    343         self.rf.close()
    344         del self.rf
    345 
    346     def next(self):
    347         l = self.readline()
    348         if l:
    349             return l
    350         raise StopIteration
    351 
    352     def __iter__(self):
    353         return self
    354 
    355 
    356 PushTimer = ccpProfile.PushTimer
    357 PopTimer = ccpProfile.PopTimer
    358 CurrentTimer = ccpProfile.CurrentTimer
    359 EnterTasklet = ccpProfile.EnterTasklet
    360 ReturnFromTasklet = ccpProfile.ReturnFromTasklet
    361 Timer = ccpProfile.Timer
    362 TimerPush = ccpProfile.TimerPush
    363 TimedFunction = ccpProfile.TimedFunction
    364 blue.TaskletExt = TaskletExt
    365 blue.tasklets = tasklets
    366 stackless.taskletext = TaskletExt
    367 
    368 def GetBlueInfo(numMinutes = None, isYield = True):
    369     if numMinutes:
    370         trend = blue.pyos.cpuUsage[-numMinutes * 60 / 10:]
    371     else:
    372         trend = blue.pyos.cpuUsage[:]
    373     mega = 1.0 / 1024.0 / 1024.0
    374     ret = util.KeyVal()
    375     ret.memData = []
    376     ret.pymemData = []
    377     ret.bluememData = []
    378     ret.othermemData = []
    379     ret.threadCpuData = []
    380     ret.procCpuData = []
    381     ret.threadKerData = []
    382     ret.procKerData = []
    383     ret.timeData = []
    384     ret.latenessData = []
    385     ret.schedData = []
    386     latenessBase = 100000000.0
    387     if len(trend) >= 1:
    388         ret.actualmin = int((trend[-1].timestamp - trend[0].timestamp) / 10000000.0 / 60.0)
    389         t1 = trend[0].timestamp
    390     benice = blue.pyos.BeNice
    391     mem = 0
    392     for sample in trend:
    393         if isYield:
    394             benice()
    395         elap = sample.timestamp - t1
    396         t1 = sample.timestamp
    397         p_elap = 100.0 / elap if elap else 0.0
    398         ret.memData.append(sample.virtualMemory * mega)
    399         ret.pymemData.append(sample.pythonMemoryUsage * mega)
    400         thread_u, proc_u = sample.userThreadCpuUsage, sample.userProcessCpuUsage
    401         thread_k, proc_k = sample.kernelThreadCpuUsage, sample.kernelProcessCpuUsage
    402         thread_cpupct = thread_u * p_elap
    403         proc_cpupct = proc_u * p_elap
    404         thread_kerpct = thread_k * p_elap
    405         proc_kerpct = proc_k * p_elap
    406         ret.threadCpuData.append(thread_cpupct)
    407         ret.procCpuData.append(proc_cpupct)
    408         ret.threadKerData.append(thread_kerpct)
    409         ret.procKerData.append(proc_kerpct)
    410         sched = (sample.fps,
    411          sample.taskletsProcessed,
    412          sample.taskletsYielding,
    413          sample.taskletsSleeping,
    414          sample.taskletsSchedulerDuration,
    415          sample.taskletsQueued)
    416         ret.schedData.append(sched)
    417         ret.timeData.append(sample.timestamp)
    418         late = 0.0
    419         if elap:
    420             late = (elap - latenessBase) / latenessBase * 100
    421         ret.latenessData.append(late)
    422 
    423     ret.proc_cpupct = proc_cpupct
    424     ret.mem = mem
    425     return ret
    426 
    427 
    428 def get_blue_info_last_tick():
    429     result = {}
    430     stats = blue.pyos.cpuUsage[-1:][0]
    431     result['virtualmemory'] = stats.virtualMemory
    432     result['pymemory'] = stats.pythonMemoryUsage
    433     result['workingset'] = stats.workingSetSize
    434     result['pagefaults'] = stats.pageFaultCount
    435     user_thread, user_process = stats.userThreadCpuUsage, stats.userProcessCpuUsage
    436     kernel_thread, kernel_process = stats.kernelThreadCpuUsage, stats.kernelProcessCpuUsage
    437     result['user_thread_time_micro'] = user_thread * 0.1
    438     result['user_process_time_micro'] = user_process * 0.1
    439     result['kernel_thread_time_micro'] = kernel_thread * 0.1
    440     result['kernel_process_time_micro'] = kernel_process * 0.1
    441     spf = 1.0 / stats.fps if stats.fps > 0.1 else 0
    442     result['tasklets_processed'] = stats.taskletsProcessed
    443     result['tasklets_queued'] = stats.taskletsQueued
    444     result['tasklet_scheduler_duration'] = stats.taskletsSchedulerDuration
    445     result['tasklets_sleeping'] = stats.taskletsSleeping
    446     result['tasklets_yielding'] = stats.taskletsYielding
    447     result['spf'] = spf
    448     return result
    449 
    450 
    451 def Terminate(exit_code, reason = ''):
    452     if not isinstance(exit_code, (int, long)):
    453         raise TypeError('exit_code must be an integer value.')
    454     import logmodule as log
    455     if exit_code == 0:
    456         log.general.Log('bluepy.Terminate - Reason: %s' % reason, log.LGNOTICE)
    457     else:
    458         log.general.Log('bluepy.Terminate - Reason: %s' % reason, log.LGERR)
    459     try:
    460         if 'sm' in __builtins__:
    461             sm.ChainEvent('ProcessShutdown')
    462     except:
    463         log.LogException()
    464 
    465     log.general.Log('Terminate - all ProcessShutdown done', log.LGNOTICE)
    466     atexit._run_exitfuncs()
    467     log.general.Log('Terminate - atexit done, about to shut down', log.LGNOTICE)
    468     blue.os.Terminate(exit_code)
    469 
    470 
    471 def TerminateSilently(exit_code, reason = ''):
    472     if not isinstance(exit_code, (int, long)):
    473         raise TypeError('exit_code must be an integer value.')
    474     import logmodule as log
    475     if exit_code == 0:
    476         log.general.Log('bluepy.Terminate - Reason: %s' % reason, log.LGNOTICE)
    477     else:
    478         log.general.Log('bluepy.Terminate - Reason: %s' % reason, log.LGERR)
    479     atexit._run_exitfuncs()
    480     blue.os.Terminate(exit_code)