-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathmain.py
202 lines (147 loc) · 5.82 KB
/
main.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
import aiohttp
import asyncio
def url(port: int, scenario: int):
return f'http://localhost:{port}/{scenario}'
# Note: Request creation code is intentionally not shared across scenarios
async def scenario1(port: int):
async with aiohttp.ClientSession() as session:
async def req():
async with session.get(url(port, 1)) as response:
return await response.text()
req1 = asyncio.create_task(req())
req2 = asyncio.create_task(req())
reqs = [req1, req2]
done, pending = await asyncio.wait(reqs, return_when=asyncio.FIRST_COMPLETED)
for task in pending:
task.cancel()
return await list(done)[0]
async def scenario2(port: int):
async with aiohttp.ClientSession() as session:
async def req():
async with session.get(url(port, 2)) as response:
return await response.text()
req1 = asyncio.create_task(req())
req2 = asyncio.create_task(req())
reqs = [req1, req2]
for coro in asyncio.as_completed(reqs):
try:
result = await coro
for req in reqs:
req.cancel()
return result
except aiohttp.client_exceptions.ServerDisconnectedError:
pass
# currently not working
async def scenario3(port: int):
connector = aiohttp.TCPConnector(limit=10000)
async with aiohttp.ClientSession(connector=connector) as session:
async def req():
async with session.get(url(port, 3)) as response:
return await response.text()
reqs = [asyncio.create_task(req()) for _ in range(10_000)]
iterable = await asyncio.wait(reqs, return_when=asyncio.FIRST_COMPLETED)
done = next(iterable)
print(done)
return await done
# currently not working
async def scenario4(port: int):
async with aiohttp.ClientSession() as session:
async def req():
async with session.get(url(port, 4)) as response:
return await response.text()
req1 = asyncio.create_task(req())
req2 = asyncio.wait_for(asyncio.create_task(req()), timeout=1)
reqs = [req1, req2]
done, pending = await asyncio.wait(reqs, return_when=asyncio.FIRST_COMPLETED)
for task in pending:
task.cancel()
return await list(done)[0]
# note: this does not cancel any other losers
async def scenario5(port: int):
async with aiohttp.ClientSession() as session:
async def req():
async with session.get(url(port, 5)) as response:
if response.status != 200:
raise Exception("invalid response")
return await response.text()
req1 = asyncio.create_task(req())
req2 = asyncio.create_task(req())
results = await asyncio.gather(req1, req2, return_exceptions=True)
for result in results:
if not isinstance(result, Exception):
return result
async def scenario6(port: int):
async with aiohttp.ClientSession() as session:
async def req():
async with session.get(url(port, 6)) as response:
if response.status != 200:
raise ValueError("invalid response")
return await response.text()
req1 = asyncio.create_task(req())
req2 = asyncio.create_task(req())
req3 = asyncio.create_task(req())
reqs = [req1, req2, req3]
for coro in asyncio.as_completed(reqs):
try:
result = await coro
for req in reqs:
req.cancel()
return result
except ValueError:
pass
async def scenario7(port: int):
async with aiohttp.ClientSession() as session:
async def req():
async with session.get(url(port, 7)) as response:
return await response.text()
async def hedge():
await asyncio.sleep(3)
return await req()
req1 = asyncio.create_task(req())
req2 = asyncio.create_task(hedge())
reqs = [req1, req2]
done, pending = await asyncio.wait(reqs, return_when=asyncio.FIRST_COMPLETED)
for task in pending:
task.cancel()
return await list(done)[0]
# currently not working
async def scenario8(port: int):
async with aiohttp.ClientSession() as session:
raise NotImplementedError
async def scenario9(port: int):
async with aiohttp.ClientSession() as session:
async def req():
resp = await session.get(url(port, 9))
from datetime import datetime
now = datetime.now()
return now, resp
reqs = [asyncio.create_task(req()) for _ in range(10)]
(done, _) = await asyncio.wait(reqs, return_when=asyncio.ALL_COMPLETED)
valid = list(filter(lambda task: task.result()[1].status == 200, done))
async def text(task):
return task.result()[0], await task.result()[1].text()
letters = [await text(task) for task in valid]
ordered = sorted(letters, key=lambda time_and_letter: time_and_letter[0])
import functools
return functools.reduce(lambda acc, time_and_letter: acc + time_and_letter[1], ordered, "")
async def main():
result1 = await scenario1(8080)
print(result1)
result2 = await scenario2(8080)
print(result2)
# result3 = await scenario3(8080)
# print(result3)
# result4 = await scenario4(8080)
# print(result4)
result5 = await scenario5(8080)
print(result5)
result6 = await scenario6(8080)
print(result6)
result7 = await scenario7(8080)
print(result7)
# result8 = await scenario8(8080)
# print(result8)
result9 = await scenario9(8080)
print(result9)
if __name__ == "__main__":
asyncio.run(main())