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

WSGIService.py (6384B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\script\net\WSGIService.py
      2 import socket
      3 import uthread
      4 import blue
      5 import log
      6 from carbon.common.script.sys.service import Service
      7 from carbon.common.script.sys.serviceConst import ROLE_SERVICE, SERVICE_RUNNING, SERVICE_STOPPED
      8 from cherrypy import wsgiserver
      9 from cherrypy.wsgiserver.ssl_builtin import BuiltinSSLAdapter
     10 
     11 class TaskletThreadPool(object):
     12 
     13     def __init__(self, server, min = 10, max = -1):
     14         self.server = server
     15         self.min = min
     16 
     17     def start(self):
     18         pass
     19 
     20     def stop(self, timeout = None):
     21         pass
     22 
     23     def put(self, obj):
     24         if obj is wsgiserver._SHUTDOWNREQUEST:
     25             return
     26         t = uthread.new(self.Run, obj)
     27         t.context = 'WSGIService::GenericTaskletThreadPool'
     28         t.run()
     29 
     30     def Run(self, conn):
     31         conn.socket.setblockingsend(self.server.service.blockingSend)
     32         try:
     33             try:
     34                 conn.communicate()
     35             finally:
     36                 conn.close()
     37 
     38         except (KeyboardInterrupt, SystemExit) as exc:
     39             self.server.interrupt = exc
     40 
     41 
     42 wsgiserver.ThreadPool = TaskletThreadPool
     43 
     44 class MyCherryPyWSGIServer(wsgiserver.CherryPyWSGIServer):
     45 
     46     def bind(self, family, type, proto = 0):
     47         super(MyCherryPyWSGIServer, self).bind(family, type, proto)
     48         self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 0)
     49 
     50 
     51 class CherryServerRunner(object):
     52 
     53     def __init__(self, server, ntasks = 2, ssl = False):
     54         self.server = server
     55         self.running = False
     56         self.ntasks = ntasks - 1
     57         self.listening = 0
     58         wsgiserver.LogError = self.LogCherryError
     59 
     60     def Start(self):
     61         self.running = True
     62         uthread.new(self._ServeFirst)
     63         if self.ntasks:
     64             blue.pyos.synchro.SleepWallclock(1)
     65             for t in xrange(self.ntasks):
     66                 self.listening += 1
     67                 uthread.new(self._ServeOthers)
     68 
     69     def Stop(self):
     70         self.running = False
     71         self.server.stop()
     72         del self.server
     73 
     74     def LogCherryError(self):
     75         log.LogException('CherryPy server internal error')
     76 
     77     def _ServeFirst(self):
     78         self.server.start()
     79 
     80     def _ServeOthers(self):
     81         try:
     82             while self.running and self.server.ready:
     83                 self.server.tick()
     84 
     85         finally:
     86             self.running = False
     87             self.listening -= 1
     88 
     89     def on_wrap_start(self):
     90         self.listening -= 1
     91         if self.listening < self.ntasks:
     92             self.listening += 1
     93             uthread.new(self.wrap_task)
     94 
     95     def on_wrap_done(self):
     96         self.listening += 1
     97 
     98     def wrap_task(self):
     99         try:
    100             if self.running and self.server.ready:
    101                 self.server.tick()
    102         finally:
    103             self.listening -= 1
    104 
    105 
    106 class SSLAdapter(BuiltinSSLAdapter):
    107     runner = None
    108 
    109     def wrap(self, socket):
    110         if self.runner:
    111             self.runner.on_wrap_start()
    112         result = super(SSLAdapter, self).wrap(socket)
    113         if self.runner:
    114             self.runner.on_wrap_done()
    115         return result
    116 
    117 
    118 class WSGIService(Service):
    119     __exportedcalls__ = {'StartServer': [ROLE_SERVICE],
    120      'StopServer': [ROLE_SERVICE]}
    121     __guid__ = 'svc.WSGIService'
    122     __dependencies__ = []
    123     __configvalues__ = {'blockingSend': False}
    124 
    125     def OnSetConfigValue(self, key, value):
    126         if key == 'blockingSend':
    127             value = bool(value)
    128         return value
    129 
    130     def GetHtmlStateDetails(self, k, v, detailed):
    131         if k == 'blockingSend':
    132             return ('block on send', v)
    133 
    134     def Run(self, memStream = None):
    135         self.runners = {}
    136         self.state = SERVICE_RUNNING
    137         self.idx = 1
    138         for key in self.__configvalues__.iterkeys():
    139             val = getattr(self, key)
    140             self.OnSetConfigValue(key, val)
    141 
    142     def Stop(self, memStream = None):
    143         for runner in self.runners:
    144             runner.Stop()
    145 
    146         self.runners = {}
    147         self.state = SERVICE_STOPPED
    148 
    149     def Restart(self):
    150         self.LogInfo('Restarting WSGIService')
    151         for idx, (args, runners) in self.runners.items():
    152             self.LogInfo('Restarting WSGI Server ' + repr(args))
    153             self.StopRunners(runners)
    154             self.runners[idx] = (args, self.StartServerInt(args))
    155 
    156     def StartServer(self, middleware, port, protocol = 'HTTP/1.1', enableIPv6 = True, serverName = None, ssl = None):
    157         args = (middleware,
    158          port,
    159          protocol,
    160          enableIPv6,
    161          serverName,
    162          ssl)
    163         runners = self.StartServerInt(args)
    164         idx = self.idx
    165         self.idx += 1
    166         self.runners[idx] = (args, runners)
    167         return idx
    168 
    169     def StopServer(self, idx):
    170         self.StopRunners(self.runners[idx][1])
    171         del self.runners[idx]
    172 
    173     def StartServerInt(self, args):
    174         runners = self.StartCherry(*args)
    175         for runner in runners:
    176             runner.Start()
    177 
    178         self.LogInfo('%s WSGI server running: %r' % (type, args))
    179         return runners
    180 
    181     def StartCherry(self, middleware, port, protocol = 'HTTP/1.1', enableIPv6 = True, serverName = None, ssl = None):
    182         if ssl:
    183 
    184             def Adapter(runner):
    185                 certificate, private_key = ssl
    186                 adapter = SSLAdapter(certificate, private_key)
    187                 adapter.runner = runner
    188                 return adapter
    189 
    190         else:
    191 
    192             def Adapter(runner):
    193                 return None
    194 
    195         if enableIPv6:
    196             addr = ('::', port)
    197         else:
    198             addr = ('0.0.0.0', port)
    199         server = MyCherryPyWSGIServer(addr, middleware, request_queue_size=socket.SOMAXCONN, server_name=serverName)
    200         server.service = self
    201         runner = CherryServerRunner(server, ssl=ssl)
    202         server.ssl_adapter = Adapter(runner)
    203         runners = (runner,)
    204         if enableIPv6 and not hasattr(socket, 'IPV6_V6ONLY'):
    205             addr = ('0.0.0.0', port)
    206             server = MyCherryPyWSGIServer(addr, middleware, request_queue_size=socket.SOMAXCONN, server_name=serverName)
    207             server.service = self
    208             runner = CherryServerRunner(server, ssl=ssl)
    209             server.ssl_adapter = Adapter(runner)
    210             runners += (runner,)
    211         return runners
    212 
    213     def StopRunners(self, runners):
    214         for runner in runners:
    215             runner.Stop()