-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasync_noblock_web.py
125 lines (100 loc) · 3.97 KB
/
async_noblock_web.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# coding=UTF-8
# email:[email protected]
import time
import logging
import tornado.ioloop
import tornado.web
import tornado.options
from tornado import gen
from tornado.concurrent import run_on_executor
from concurrent.futures import ThreadPoolExecutor
tornado.options.parse_command_line()
class MainHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self):
self.write("Hello, world")
self.finish()
class ActionHandler(tornado.web.RequestHandler):
executor = ThreadPoolExecutor(4)
@gen.coroutine
def post(self):
action = self.get_argument('action', '')
print("Noagh")
if hasattr(self, action):
yield self.action_executor(action)
else:
self.write(dict(status=1, message='没有找到对应的action'))
return
@run_on_executor
def action_executor(self, action):
action_handle = getattr(self, action)
action_handle("url1", 10)
def sleep(self, url, wait):
print(url, wait)
time.sleep(wait)
print('routine_url_with_return {} took {}s to get!'.format(url, wait))
# 基于 Tornado 协议的异步库,非阻塞
class NoBlockingHnadler(tornado.web.RequestHandler):
@gen.coroutine
def get(self):
# 协程来回切换执行
# 非阻塞耗时:max(url1, url2)
start_time =time.time()
yield [self.routine_url_with_return("url1", 3), self.routine_url_with_return("url2", 7)]
self.write('Blocking Request')
print(time.time()-start_time)
@gen.coroutine
def routine_url_with_return(self, url, wait):
print(url, wait)
yield gen.sleep(wait)
print('routine_url_with_return {} took {}s to get!'.format(url, wait))
# 基于ThreadPoolExecutor线程的异步编程,非阻塞
# 缺点:大量使用线程化的异步函数做一些高负载的活动,会导致该 Tornado 进程性能低下响应缓慢
# ThreadPoolExecutor 是对标准库中的 threading 的高度封装,
# 利用线程的方式让阻塞函数异步化,解决了很多库是不支持异步的问题。
class NoBlockingHnadler2(tornado.web.RequestHandler):
executor = ThreadPoolExecutor(4)
@gen.coroutine
def get(self):
start_time =time.time()
# 协程来回切换执行
# 阻塞耗时:sum(url1, url2)
yield [self.routine_url_with_return("url1", 3), self.routine_url_with_return("url3", 7)]
#print(yield self.routine_url_with_return("url3", 7))
#yield [self.routine_url_with_return("url1", 3), self.routine_url_with_return("url3", 7)]
self.write('Blocking Request')
print(time.time()-start_time)
@run_on_executor
def routine_url_with_return(self, url, wait):
print(url, wait)
time.sleep(wait)
print('routine_url_with_return {} took {}s to get!'.format(url, wait))
return "routine_url_with_return %s"%wait
# 阻塞其他的请求, 非基于 Tornado 协议的异步库
class BlockingHnadler(tornado.web.RequestHandler):
executor = ThreadPoolExecutor(4)
@gen.coroutine
def get(self):
start_time =time.time()
# 协程来回切换执行
# 阻塞耗时:sum(url1, url2)
yield [self.routine_url_with_return("url1", 3), self.routine_url_with_return("url3", 7)]
self.write('Blocking Request')
print(time.time()-start_time)
@gen.coroutine
def routine_url_with_return(self, url, wait):
print(url, wait)
yield time.sleep(wait)
print('routine_url_with_return {} took {}s to get!'.format(url, wait))
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
(r"/block", BlockingHnadler),
(r"/noblock", NoBlockingHnadler),
(r"/noblock2", NoBlockingHnadler2),
(r"/action", ActionHandler),
], autoreload=True)
if __name__ == "__main__":
app = make_app()
app.listen(8080)
tornado.ioloop.IOLoop.current().start()