tornado热加载框架
By:Roy.LiuLast updated:2019-07-04
收藏的一个tornado热加载框架
# coding:utf-8 #mvc框架总入口 import sys import os import time import re import tornado.gen import tornado.web import traceback import mvcroot import mvcroot.conf import ujson as json if(sys.version[0:2]=="2."): pass else: from importlib import reload pymodule_cache_dict={} #用来缓存加载到内存的控制器类 class MVCMainHandler(tornado.web.RequestHandler): @tornado.gen.coroutine def httprequest_handler(self,requestpath): requestpath=requestpath.strip() requestpath.replace("//","/") if(requestpath[-1:]=="/"): requestpath=requestpath[:-1] #==============================检查静态资源文件Begin==================================== extsz=os.path.splitext(requestpath) extname=extsz[1].lower() if(extname!=""): #如果请求的为静态资源 if(extname in [".txt",".css",".jpg",".gif",".png",".doc",".docx",".xls",".xlsx",""]): if(extname in mvcroot.conf.mimetype): self.set_header("Content-Type",mvcroot.conf.mimetype.get(extname,"")) #print(mvcroot.conf.mimetype.get(extname,"")) yield self.static_resource_handler(requestpath,extname) return #==============================检查静态资源文件End==================================== #==============================检测路由表中的所有url是否匹配,如果有匹配的,执行匹配的路由指向的类的page_load函数Begin================== isfindinroutemap=False #在路由表中是否找到匹配的 routerallclassname="" #匹配的路由中指向的类的完整名称 routerclassname="" #匹配的路由中指向的类的名称 routermodulename="" #匹配的路由中指向的类所在的模块名称(不包含这个文件里面的某个class类),用来__import__加载用 isurlcontainsargs=False for myroutetuple in mvcroot.conf.routemap: url = requestpath #这是url源文本 p1 = myroutetuple[0] #这是我们写的正则表达式 pattern1 = re.compile(p1)#同样是编译 matcher1 = re.findall(pattern1,url)#同样是查询 if(len(matcher1)>0): if(p1.find("(")>-1): isurlcontainsargs=True isfindinroutemap=True routerallclassname=str(myroutetuple[1])[8:-2] rfindindex=routerallclassname.rfind(".") #右边第一个.出现的位置 routermodulename=routerallclassname[0:rfindindex] routerclassname=routerallclassname[rfindindex+1:] print("routerclassname:{0},routermodulename:{1}".format(routerclassname,routermodulename)) page_args=matcher1[0] if(type(page_args)!=tuple): page_args=[page_args] print("page_args:{0}".format(page_args)) break if(isfindinroutemap==True): #如果在路由表匹配到符合的url,则执行路由处理函数 mypageclass=__import__(routermodulename,fromlist=True) #print("mypageclass:{0}".format(mypageclass)) if(mvcroot.conf.debug): reload(mypageclass) mypage= getattr(mypageclass,routerclassname)() mypage.request=self.request mypage.tornadowebinstance=self errmsg="" try: yield mypage.prepare() except Exception as ex: traceback.print_exc() mypage.isend=True self.write(traceback.format_exc().replace("\n","
")) if(mypage.isend==True): #如果控制器确定要终止执行,则到这里就停止 return try: if(isurlcontainsargs): yield mypage.page_load(*page_args) else: yield mypage.page_load() except Exception as ex: traceback.print_exc() self.write(traceback.format_exc().replace("\n","
")) return #=============================================路由处理结束================================ #======================================检查请求的html文件Begin================================= #========================如果路由没有检测到html页面的路由,则检查真正的静态文件 Begin====================== if(extname in [".htm",".html"]): self.set_header("Content-Type","text/html") yield self.static_resource_handler(requestpath,extname) return #===============================检查请求的html文件End================= #=============================按照url路径寻找并加载控制器Begin=========================== #print("requestpath:"+requestpath) patharray=requestpath.split("/") patharraylen=len(patharray) #print(patharray) controllerandmethodname="" controllername="" methodname="" if(patharraylen>1): modulepre=requestpath[0:requestpath.rfind("/")].replace("/",".") controllerandmethodname=patharray[patharraylen-1] else: modulepre="" controllerandmethodname=patharray[0] if(controllerandmethodname.find("!")>-1): sz=controllerandmethodname.split("!") controllername=sz[0] methodname=sz[1] else: controllername=controllerandmethodname #print("controllername:{0},methodname:{1},modulepre:{2}".format(controllername,methodname,modulepre)) if(controllername==""): controllername="index" #print("url中的控制器为空,将控制器名字设置为index") # self.write("必须提供控制器名称") # return if(controllername=="mvcrootdoor" or controllername=="conf"): self.write("you can't use this controller name") return pymoduleload="" #需要调用__import__加载的类名 if(modulepre!=""): pymoduleload="mvcroot."+modulepre+"."+controllername else: pymoduleload="mvcroot."+controllername #print("pymoduleload:"+pymoduleload) try: # 加载性能测试,80万次每秒的加载速度,如果是开发模式热更新的话,4000次每秒 # t1=time.time() # for i in range(0,1000): # mypageclass=__import__(pymoduleload,fromlist=True) # reload(mypageclass) # t2=time.time() # print(t2-t1) if(pymoduleload not in pymodule_cache_dict): mypageclass=__import__(pymoduleload,fromlist=True) pymodule_cache_dict[pymoduleload]=mypageclass if(mvcroot.conf.debug==True): mypageclass=__import__(pymoduleload,fromlist=True) reload(mypageclass) pymodule_cache_dict[pymoduleload]=mypageclass #print("isdebug:{0},reload controller".format(mvcroot.conf.debug)) else: #print("isdebug:{0},load controller from cache".format(mvcroot.conf.debug)) mypageclass=pymodule_cache_dict[pymoduleload] pass except Exception as ex: self.write(traceback.format_exc().replace("\n","
")) return #self.redirect() #print(mypageclass) #print(dir(self.request)) # print("arguments:{0}".format(self.request.arguments)) # print("query_arguments:{0}".format(self.request.query_arguments)) # print("body:{0}".format(self.request.body)) # print("body_arguments:{0}".format(self.request.body_arguments)) mypage=mypageclass.page() mypage.request=self.request mypage.tornadowebinstance=self errmsg="" try: yield mypage.prepare() except Exception as ex: errmsg=traceback.format_exc() traceback.print_exc() if(mypage.isend==True): #如果控制器确定要终止执行,则到这里就停止 return if(methodname==""): try: r=yield mypage.page_load() except Exception as ex: errmsg=traceback.format_exc() traceback.print_exc() else: try: methodnamerun=getattr(mypage,methodname) r=yield methodnamerun() except Exception as ex: errmsg=traceback.format_exc() traceback.print_exc() if(errmsg!=""): print(errmsg) self.write(errmsg.replace("\n","
")) return #print("执行结果:"+str(r)) rtype=type(r) #print("r type:{0}".format(rtype.__name__)) if(rtype==mvcroot.ViewReturn): viewname=r.Get() print("viewname:"+viewname) realviewfilepath="" elif(rtype==mvcroot.TextReturn): txt=r.Get() self.write(txt) elif(rtype==mvcroot.JsonReturn): jsonresult=r.Get() if(jsonresult!=None): sendtext=json.dumps(jsonresult) self.write(sendtext) elif(rtype==str): self.write(r) elif(rtype.__name__ in ["int","long","float","bool"]): self.write(str(r)) elif(rtype.__name__=="unicode"): self.write(r.encode("utf8")) elif(rtype==list or rtype==dict): self.write(json.dumps(r)) elif(r==None): #print("返回值为空值") pass else: if(hasattr(r,"__dict__")): self.write(json.dumps(r.__dict__)) mypage.request=None mypage.tornadowebinstance=None #r=self.render_string("page1.html") pass @tornado.gen.coroutine def static_resource_handler(self,requestpath,extname): realfilepath=mvcroot.rootpath+"/"+requestpath #print("realfilepath:"+realfilepath) #self.write(realfilepath) if(os.path.exists(realfilepath)): f=open(realfilepath,"rb") filecontent=f.read() f.close() self.write(filecontent) else: self.write("Static File:["+realfilepath+"] Not Exists") pass @tornado.gen.coroutine def routeHandler(self): pass @tornado.gen.coroutine def get(self,requestpath): yield self.httprequest_handler(requestpath) pass @tornado.gen.coroutine def post(self,requestpath): yield self.httprequest_handler(requestpath) pass @tornado.gen.coroutine def put(self,requestpath): yield self.httprequest_handler(requestpath) pass @tornado.gen.coroutine def delete(self, requestpath): yield self.httprequest_handler(requestpath) pass
From:一号门
Previous:老版本python2.6安装pip,psutil 报错问题。
COMMENTS