winloop 0.1.2__tar.gz → 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {winloop-0.1.2/winloop.egg-info → winloop-0.1.4}/PKG-INFO +53 -39
- {winloop-0.1.2 → winloop-0.1.4}/README.md +45 -33
- winloop-0.1.4/setup.py +122 -0
- winloop-0.1.4/tests/__init__.py +0 -0
- {winloop-0.1.2 → winloop-0.1.4}/tests/__main__.py +1 -1
- winloop-0.1.4/tests/test_aiodns.py +40 -0
- {winloop-0.1.2 → winloop-0.1.4}/tests/test_aiohttp.py +2 -0
- {winloop-0.1.2 → winloop-0.1.4}/tests/test_aiomultiprocess.py +11 -11
- winloop-0.1.4/tests/test_base.py +972 -0
- winloop-0.1.4/tests/test_context.py +791 -0
- winloop-0.1.4/tests/test_cython.py +35 -0
- winloop-0.1.4/tests/test_dealloc.py +61 -0
- winloop-0.1.4/tests/test_dns.py +256 -0
- winloop-0.1.4/tests/test_executors.py +47 -0
- winloop-0.1.4/tests/test_libuv_api.py +23 -0
- winloop-0.1.4/tests/test_process_spawning.py +115 -0
- winloop-0.1.4/tests/test_regr1.py +120 -0
- winloop-0.1.4/tests/test_runner.py +39 -0
- winloop-0.1.4/tests/test_sourcecode.py +73 -0
- winloop-0.1.4/tests/test_testbase.py +51 -0
- winloop-0.1.4/tests/test_udp.py +414 -0
- winloop-0.1.4/tests/test_unix.py +700 -0
- winloop-0.1.4/vendor/libuv/src/fs-poll.c +287 -0
- winloop-0.1.4/vendor/libuv/src/idna.c +560 -0
- winloop-0.1.4/vendor/libuv/src/inet.c +298 -0
- winloop-0.1.4/vendor/libuv/src/random.c +123 -0
- winloop-0.1.4/vendor/libuv/src/strscpy.c +38 -0
- winloop-0.1.4/vendor/libuv/src/strtok.c +52 -0
- winloop-0.1.4/vendor/libuv/src/thread-common.c +175 -0
- winloop-0.1.4/vendor/libuv/src/threadpool.c +418 -0
- winloop-0.1.4/vendor/libuv/src/timer.c +200 -0
- winloop-0.1.4/vendor/libuv/src/uv-common.c +1029 -0
- winloop-0.1.4/vendor/libuv/src/uv-data-getter-setters.c +119 -0
- winloop-0.1.4/vendor/libuv/src/version.c +45 -0
- winloop-0.1.4/vendor/libuv/src/win/async.c +98 -0
- winloop-0.1.4/vendor/libuv/src/win/core.c +777 -0
- winloop-0.1.4/vendor/libuv/src/win/detect-wakeup.c +56 -0
- winloop-0.1.4/vendor/libuv/src/win/dl.c +135 -0
- winloop-0.1.4/vendor/libuv/src/win/error.c +173 -0
- winloop-0.1.4/vendor/libuv/src/win/fs-event.c +598 -0
- winloop-0.1.4/vendor/libuv/src/win/fs.c +3426 -0
- winloop-0.1.4/vendor/libuv/src/win/getaddrinfo.c +383 -0
- winloop-0.1.4/vendor/libuv/src/win/getnameinfo.c +146 -0
- winloop-0.1.4/vendor/libuv/src/win/handle.c +162 -0
- winloop-0.1.4/vendor/libuv/src/win/loop-watcher.c +122 -0
- winloop-0.1.4/vendor/libuv/src/win/pipe.c +2672 -0
- winloop-0.1.4/vendor/libuv/src/win/poll.c +586 -0
- winloop-0.1.4/vendor/libuv/src/win/process-stdio.c +416 -0
- winloop-0.1.4/vendor/libuv/src/win/process.c +1397 -0
- winloop-0.1.4/vendor/libuv/src/win/signal.c +282 -0
- winloop-0.1.4/vendor/libuv/src/win/snprintf.c +42 -0
- winloop-0.1.4/vendor/libuv/src/win/stream.c +252 -0
- winloop-0.1.4/vendor/libuv/src/win/tcp.c +1668 -0
- winloop-0.1.4/vendor/libuv/src/win/thread.c +470 -0
- winloop-0.1.4/vendor/libuv/src/win/tty.c +2422 -0
- winloop-0.1.4/vendor/libuv/src/win/udp.c +1137 -0
- winloop-0.1.4/vendor/libuv/src/win/util.c +1707 -0
- winloop-0.1.4/vendor/libuv/src/win/winapi.c +147 -0
- winloop-0.1.4/vendor/libuv/src/win/winsock.c +575 -0
- {winloop-0.1.2 → winloop-0.1.4}/winloop/__init__.py +52 -61
- {winloop-0.1.2 → winloop-0.1.4}/winloop/_noop.py +0 -1
- {winloop-0.1.2 → winloop-0.1.4}/winloop/_testbase.py +100 -91
- winloop-0.1.4/winloop/_version.py +13 -0
- {winloop-0.1.2 → winloop-0.1.4}/winloop/loop.c +54901 -54414
- {winloop-0.1.2 → winloop-0.1.4}/winloop/loop.pyi +15 -27
- {winloop-0.1.2 → winloop-0.1.4/winloop.egg-info}/PKG-INFO +53 -39
- winloop-0.1.4/winloop.egg-info/SOURCES.txt +72 -0
- winloop-0.1.2/setup.py +0 -96
- winloop-0.1.2/tests/__init__.py +0 -1
- winloop-0.1.2/winloop/includes/context.h +0 -38
- winloop-0.1.2/winloop.egg-info/SOURCES.txt +0 -21
- winloop-0.1.2/winloop.egg-info/requires.txt +0 -1
- {winloop-0.1.2 → winloop-0.1.4}/LICENSE-APACHE +0 -0
- {winloop-0.1.2 → winloop-0.1.4}/LICENSE-MIT +0 -0
- {winloop-0.1.2 → winloop-0.1.4}/pyproject.toml +0 -0
- {winloop-0.1.2 → winloop-0.1.4}/setup.cfg +0 -0
- {winloop-0.1.2 → winloop-0.1.4}/winloop/includes/__init__.py +0 -0
- {winloop-0.1.2 → winloop-0.1.4}/winloop.egg-info/dependency_links.txt +0 -0
- {winloop-0.1.2 → winloop-0.1.4}/winloop.egg-info/top_level.txt +0 -0
|
@@ -1,32 +1,36 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: winloop
|
|
3
|
-
Version: 0.1.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.1.4
|
|
4
|
+
Summary: Windows version of uvloop
|
|
5
5
|
Author: Vizonex
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
Keywords: winloop,libuv,windows,fast-asyncio,uvloop-alternative
|
|
7
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
9
11
|
Classifier: Programming Language :: Python :: 3.9
|
|
10
12
|
Classifier: Programming Language :: Python :: 3.10
|
|
11
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
15
|
Classifier: Intended Audience :: Developers
|
|
13
16
|
Classifier: Framework :: AsyncIO
|
|
14
17
|
Description-Content-Type: text/markdown
|
|
15
18
|
License-File: LICENSE-APACHE
|
|
16
19
|
License-File: LICENSE-MIT
|
|
17
|
-
Requires-Dist: cython
|
|
18
20
|
|
|
19
21
|
<img src="https://raw.githubusercontent.com/Vizonex/Winloop/main/winloop.png" width="200px"/>
|
|
22
|
+
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
|
|
20
23
|
|
|
21
24
|
# Winloop
|
|
22
|
-
An Alternative library for uvloop
|
|
23
|
-
I never really liked the fact that I couldn't make anything run faster escpecially when you have fiber internet connections in place and you've done all the optimizations you could possibly think of. It always felt disappointing when `libuv` is
|
|
25
|
+
An Alternative library for uvloop compatibility with windows because let's face it. Window's python asyncio standard libaray is garabage escpecially when Windows Defender decides to eat half your ram.
|
|
26
|
+
I never really liked the fact that I couldn't make anything run faster escpecially when you have fiber internet connections in place and you've done all the optimizations you could possibly think of. It always felt disappointing when `libuv` is available for windows [but windows was never compatible with uvloop.](https://github.com/MagicStack/uvloop/issues/14#issuecomment-575826367])
|
|
24
27
|
|
|
25
|
-
Because nobody was willing to step in after so many years of waiting, I went ahead and downloaded the source code for uvloop and started modifying the source code to be windows
|
|
28
|
+
Because nobody was willing to step in after so many years of waiting, I went ahead and downloaded the source code for uvloop and started modifying the source code to be windows compatible by carefully removing and changing parts that were not made for windows. Many hours of research went into making this library exist.
|
|
26
29
|
|
|
27
30
|
The differences with __uvloop__ is that forking has been fully disabled and some smaller api calls had to be changed, error handling has been carefully modified and subprocesses instead release the gil instead of forking out...
|
|
28
31
|
|
|
29
|
-
There is a
|
|
32
|
+
There is a performance increase of about 5 times vs using the `WindowsSelectorEventLoopPolicy` and `WindowsProactorEventLoopPolicy` which have been known to trigger ssl problems in `python 3.9`. Winloop is a very good replacement for solving those ssl problem as well. This library also has comparable performance to it's brother uvloop.
|
|
33
|
+
|
|
30
34
|
|
|
31
35
|
|
|
32
36
|
## How to install Winloop on your Windows Operating System
|
|
@@ -35,17 +39,21 @@ There is a perfromance increase of about 5 times vs using the `WindowsSelectorEv
|
|
|
35
39
|
pip install winloop
|
|
36
40
|
```
|
|
37
41
|
|
|
38
|
-
You can also clone the reposity and build the extension yourself by running the command below if you wish to use or build this library locally, Note that you will need Cython and The Visual C++ extensions
|
|
39
|
-
to compile this library on your own.
|
|
42
|
+
You can also clone the reposity and build the extension yourself by running the command below if you wish to use or build this library locally, Note that you will need Cython and The Visual C++ extensions
|
|
43
|
+
to compile this library on your own.
|
|
40
44
|
|
|
41
45
|
```
|
|
42
|
-
python setup.py build_ext --inplace
|
|
46
|
+
python setup.py build_ext --inplace
|
|
43
47
|
```
|
|
44
48
|
|
|
45
49
|
## Issues Reporting
|
|
46
50
|
|
|
47
51
|
If you find any bugs with this library be sure to open up an issue to our github repo. Me and other contributors will be happy try to help you figure out and diagnose your problems.
|
|
48
52
|
|
|
53
|
+
## Making pull requests
|
|
54
|
+
We encourage anyone to make pull-requests to winloop from spelling mistakes to vulnerability patches. Every little bit helps keep this library maintained and alive.
|
|
55
|
+
Make sure that you are able to compile the library with the steps shown above. We plan to implement a nightly workflow to verify one's pull request in the future.
|
|
56
|
+
|
|
49
57
|
|
|
50
58
|
|
|
51
59
|
```python
|
|
@@ -66,7 +74,7 @@ import sys
|
|
|
66
74
|
class TestAioHTTP(unittest.TestCase):
|
|
67
75
|
def __init__(self, methodName: str = "test_aiohttp_basic_1") -> None:
|
|
68
76
|
super().__init__(methodName)
|
|
69
|
-
|
|
77
|
+
|
|
70
78
|
|
|
71
79
|
def setUp(self):
|
|
72
80
|
self.loop = asyncio.get_event_loop()
|
|
@@ -164,42 +172,43 @@ if __name__ == "__main__":
|
|
|
164
172
|
# asyncio.DefaultEventLoopPolicy = asyncio.WindowsSelectorEventLoopPolicy
|
|
165
173
|
# asyncio.DefaultEventLoopPolicy = asyncio.WindowsProactorEventLoopPolicy
|
|
166
174
|
unittest.main()
|
|
167
|
-
# Looks like winloop might be 3x faster than the Proctor Event Loop , THAT's A HUGE IMPROVEMENT!
|
|
175
|
+
# Looks like winloop might be 3x faster than the Proctor Event Loop , THAT's A HUGE IMPROVEMENT!
|
|
168
176
|
print("testing again but with winloop enabled")
|
|
169
177
|
winloop.install()
|
|
170
178
|
unittest.main()
|
|
171
179
|
```
|
|
172
180
|
|
|
173
|
-
The benchmarks for the code above are as follows
|
|
181
|
+
The benchmarks for the code above are as follows
|
|
174
182
|
|
|
175
183
|
## Benchmarks
|
|
176
184
|
|
|
177
|
-
### TCP Connections
|
|
185
|
+
### TCP Connections
|
|
178
186
|
-------------------
|
|
179
187
|
|
|
180
|
-
| Asyncio Event Loop Policy | Time (in Seconds) |
|
|
188
|
+
| Asyncio Event Loop Policy | Time (in Seconds) |
|
|
181
189
|
|-----------------------------------|-----------------------|
|
|
182
190
|
| WinLoopPolicy | 0.493s |
|
|
183
191
|
| WindowsProactorEventLoopPolicy | 2.510s |
|
|
184
192
|
| WindowsSelectorEventLoopPolicy | 2.723s |
|
|
185
193
|
|
|
186
194
|
|
|
187
|
-
That's a massive increase and jump from just TCP alone I'll be posting more benchmarks soon as
|
|
195
|
+
That's a massive increase and jump from just TCP alone I'll be posting more benchmarks soon as
|
|
188
196
|
I modify more of the current test suites made by uvloop...
|
|
189
197
|
|
|
190
198
|
|
|
191
|
-
## How to Use Winloop with Fastapi
|
|
199
|
+
## How to Use Winloop with Fastapi
|
|
192
200
|
|
|
193
201
|
This was a cool little script I put together Just to make fastapi that much faster to handle
|
|
194
202
|
|
|
195
203
|
```python
|
|
196
204
|
|
|
205
|
+
# TODO this code example is deprecated
|
|
197
206
|
from fastapi import FastAPI
|
|
198
207
|
from fastapi.responses import HTMLResponse
|
|
199
|
-
import winloop
|
|
208
|
+
import winloop
|
|
200
209
|
import uvicorn
|
|
201
|
-
import asyncio
|
|
202
|
-
import datetime
|
|
210
|
+
import asyncio
|
|
211
|
+
import datetime
|
|
203
212
|
|
|
204
213
|
app = FastAPI()
|
|
205
214
|
|
|
@@ -214,7 +223,7 @@ async def test_get_request():
|
|
|
214
223
|
return HTMLResponse("<html><body><h1>FAST API WORKS WITH WINLOOP!</h1></body></html>")
|
|
215
224
|
|
|
216
225
|
|
|
217
|
-
# starllete will use asyncio.to_thread() so that this can remain asynchronous
|
|
226
|
+
# starllete will use asyncio.to_thread() so that this can remain asynchronous
|
|
218
227
|
@app.get("/date")
|
|
219
228
|
def test_dynamic_response():
|
|
220
229
|
return str(datetime.datetime.now())
|
|
@@ -231,14 +240,14 @@ if __name__ == "__main__":
|
|
|
231
240
|
```
|
|
232
241
|
|
|
233
242
|
|
|
234
|
-
## How To Use Winloop When Uvloop is not
|
|
243
|
+
## How To Use Winloop When Uvloop is not available
|
|
235
244
|
|
|
236
245
|
```python
|
|
237
246
|
|
|
238
|
-
# Here's A small Example of using winloop when uvloop is not
|
|
247
|
+
# Here's A small Example of using winloop when uvloop is not available to us
|
|
239
248
|
import sys
|
|
240
249
|
import aiohttp
|
|
241
|
-
import asyncio
|
|
250
|
+
import asyncio
|
|
242
251
|
|
|
243
252
|
async def main():
|
|
244
253
|
async with aiohttp.ClientSession("https://httpbin.org") as client:
|
|
@@ -250,29 +259,34 @@ if __name__ == "__main__":
|
|
|
250
259
|
from winloop import run
|
|
251
260
|
else:
|
|
252
261
|
# if we're on apple or linux do this instead
|
|
253
|
-
from uvloop import run
|
|
262
|
+
from uvloop import run
|
|
254
263
|
run(main())
|
|
255
264
|
```
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
## Possible Upcomming Features/Optimizations to Winloop / This is also our TODO list
|
|
259
|
-
I have been looking deeply into some of the proposed Pulls and changes to `Uvloop` and I will be tuning in and listening to what's going on uvloop's end to see what we might have to change . This is a list of features I would like to implement from likely to least likely to be done as well as solved. If any of these feature have been added you will simply know by the fact that It won't be on this list anymore...
|
|
260
265
|
|
|
261
|
-
- Nightly Builds And Test Suite Workflows for anyone wanting to use newer unreleased versions.
|
|
262
266
|
|
|
263
|
-
|
|
267
|
+
## TODO-List
|
|
268
|
+
|
|
269
|
+
- Update Fastapi Example to a more recent version of fastapi
|
|
270
|
+
|
|
271
|
+
- Contact uvicorn about this [issue](https://github.com/Vizonex/Winloop/issues/11) I have a funny feeling something is going on here...
|
|
264
272
|
|
|
265
|
-
-
|
|
273
|
+
- Nightly Builds And Test Suite Workflows for anyone wanting to use newer unreleased versions.
|
|
266
274
|
|
|
267
275
|
- Drop All `DEF` Macros, I'm currently seeking help on replacements for macros where all the variables are known about at compile-time
|
|
268
276
|
|
|
269
|
-
- Adding in the
|
|
277
|
+
- Adding in the necessary hooks for pyinstaller to compile this fast library to executable code even though hooks have been known to inflate the size of the `.exe` files. This is because calling hidden-imports for all the `__init__.py` modules might annoy some developers. (Luckily I'm aware of this issue because I've been doing this myself...)
|
|
278
|
+
|
|
279
|
+
- write a workflow for compiling libuv on different versions of windows when distributing out pypi wheels.
|
|
270
280
|
|
|
271
|
-
-
|
|
281
|
+
- write a workflow for nightly builds if necessary for verification of pull requests.
|
|
272
282
|
|
|
273
|
-
- Sphinx Styled Documentation (Maybe I
|
|
283
|
+
- Sphinx Styled Documentation (Maybe I'm thinking about it...)
|
|
274
284
|
|
|
285
|
+
- Update benchmarks (They are old) can't believe I maintained this project for over a year now...
|
|
275
286
|
|
|
276
287
|
## Videos
|
|
277
288
|
- By me: https://www.youtube.com/watch?v=tz9RYJ6aBZ8 (I might make a tutorial on how to use and install winloop it for those who have reading problems)
|
|
278
|
-
- My Presentation and Virtual Confrence: https://www.youtube.com/watch?v=Cbb6trkKWXY
|
|
289
|
+
- My Presentation and Virtual Confrence: https://www.youtube.com/watch?v=Cbb6trkKWXY
|
|
290
|
+
|
|
291
|
+
## Contributing
|
|
292
|
+
I put my heart and soul into this library ever since it began and any help is apperciated and means a lot to me.
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
<img src="https://raw.githubusercontent.com/Vizonex/Winloop/main/winloop.png" width="200px"/>
|
|
2
|
+
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
|
|
2
3
|
|
|
3
4
|
# Winloop
|
|
4
|
-
An Alternative library for uvloop
|
|
5
|
-
I never really liked the fact that I couldn't make anything run faster escpecially when you have fiber internet connections in place and you've done all the optimizations you could possibly think of. It always felt disappointing when `libuv` is
|
|
5
|
+
An Alternative library for uvloop compatibility with windows because let's face it. Window's python asyncio standard libaray is garabage escpecially when Windows Defender decides to eat half your ram.
|
|
6
|
+
I never really liked the fact that I couldn't make anything run faster escpecially when you have fiber internet connections in place and you've done all the optimizations you could possibly think of. It always felt disappointing when `libuv` is available for windows [but windows was never compatible with uvloop.](https://github.com/MagicStack/uvloop/issues/14#issuecomment-575826367])
|
|
6
7
|
|
|
7
|
-
Because nobody was willing to step in after so many years of waiting, I went ahead and downloaded the source code for uvloop and started modifying the source code to be windows
|
|
8
|
+
Because nobody was willing to step in after so many years of waiting, I went ahead and downloaded the source code for uvloop and started modifying the source code to be windows compatible by carefully removing and changing parts that were not made for windows. Many hours of research went into making this library exist.
|
|
8
9
|
|
|
9
10
|
The differences with __uvloop__ is that forking has been fully disabled and some smaller api calls had to be changed, error handling has been carefully modified and subprocesses instead release the gil instead of forking out...
|
|
10
11
|
|
|
11
|
-
There is a
|
|
12
|
+
There is a performance increase of about 5 times vs using the `WindowsSelectorEventLoopPolicy` and `WindowsProactorEventLoopPolicy` which have been known to trigger ssl problems in `python 3.9`. Winloop is a very good replacement for solving those ssl problem as well. This library also has comparable performance to it's brother uvloop.
|
|
13
|
+
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
## How to install Winloop on your Windows Operating System
|
|
@@ -17,17 +19,21 @@ There is a perfromance increase of about 5 times vs using the `WindowsSelectorEv
|
|
|
17
19
|
pip install winloop
|
|
18
20
|
```
|
|
19
21
|
|
|
20
|
-
You can also clone the reposity and build the extension yourself by running the command below if you wish to use or build this library locally, Note that you will need Cython and The Visual C++ extensions
|
|
21
|
-
to compile this library on your own.
|
|
22
|
+
You can also clone the reposity and build the extension yourself by running the command below if you wish to use or build this library locally, Note that you will need Cython and The Visual C++ extensions
|
|
23
|
+
to compile this library on your own.
|
|
22
24
|
|
|
23
25
|
```
|
|
24
|
-
python setup.py build_ext --inplace
|
|
26
|
+
python setup.py build_ext --inplace
|
|
25
27
|
```
|
|
26
28
|
|
|
27
29
|
## Issues Reporting
|
|
28
30
|
|
|
29
31
|
If you find any bugs with this library be sure to open up an issue to our github repo. Me and other contributors will be happy try to help you figure out and diagnose your problems.
|
|
30
32
|
|
|
33
|
+
## Making pull requests
|
|
34
|
+
We encourage anyone to make pull-requests to winloop from spelling mistakes to vulnerability patches. Every little bit helps keep this library maintained and alive.
|
|
35
|
+
Make sure that you are able to compile the library with the steps shown above. We plan to implement a nightly workflow to verify one's pull request in the future.
|
|
36
|
+
|
|
31
37
|
|
|
32
38
|
|
|
33
39
|
```python
|
|
@@ -48,7 +54,7 @@ import sys
|
|
|
48
54
|
class TestAioHTTP(unittest.TestCase):
|
|
49
55
|
def __init__(self, methodName: str = "test_aiohttp_basic_1") -> None:
|
|
50
56
|
super().__init__(methodName)
|
|
51
|
-
|
|
57
|
+
|
|
52
58
|
|
|
53
59
|
def setUp(self):
|
|
54
60
|
self.loop = asyncio.get_event_loop()
|
|
@@ -146,42 +152,43 @@ if __name__ == "__main__":
|
|
|
146
152
|
# asyncio.DefaultEventLoopPolicy = asyncio.WindowsSelectorEventLoopPolicy
|
|
147
153
|
# asyncio.DefaultEventLoopPolicy = asyncio.WindowsProactorEventLoopPolicy
|
|
148
154
|
unittest.main()
|
|
149
|
-
# Looks like winloop might be 3x faster than the Proctor Event Loop , THAT's A HUGE IMPROVEMENT!
|
|
155
|
+
# Looks like winloop might be 3x faster than the Proctor Event Loop , THAT's A HUGE IMPROVEMENT!
|
|
150
156
|
print("testing again but with winloop enabled")
|
|
151
157
|
winloop.install()
|
|
152
158
|
unittest.main()
|
|
153
159
|
```
|
|
154
160
|
|
|
155
|
-
The benchmarks for the code above are as follows
|
|
161
|
+
The benchmarks for the code above are as follows
|
|
156
162
|
|
|
157
163
|
## Benchmarks
|
|
158
164
|
|
|
159
|
-
### TCP Connections
|
|
165
|
+
### TCP Connections
|
|
160
166
|
-------------------
|
|
161
167
|
|
|
162
|
-
| Asyncio Event Loop Policy | Time (in Seconds) |
|
|
168
|
+
| Asyncio Event Loop Policy | Time (in Seconds) |
|
|
163
169
|
|-----------------------------------|-----------------------|
|
|
164
170
|
| WinLoopPolicy | 0.493s |
|
|
165
171
|
| WindowsProactorEventLoopPolicy | 2.510s |
|
|
166
172
|
| WindowsSelectorEventLoopPolicy | 2.723s |
|
|
167
173
|
|
|
168
174
|
|
|
169
|
-
That's a massive increase and jump from just TCP alone I'll be posting more benchmarks soon as
|
|
175
|
+
That's a massive increase and jump from just TCP alone I'll be posting more benchmarks soon as
|
|
170
176
|
I modify more of the current test suites made by uvloop...
|
|
171
177
|
|
|
172
178
|
|
|
173
|
-
## How to Use Winloop with Fastapi
|
|
179
|
+
## How to Use Winloop with Fastapi
|
|
174
180
|
|
|
175
181
|
This was a cool little script I put together Just to make fastapi that much faster to handle
|
|
176
182
|
|
|
177
183
|
```python
|
|
178
184
|
|
|
185
|
+
# TODO this code example is deprecated
|
|
179
186
|
from fastapi import FastAPI
|
|
180
187
|
from fastapi.responses import HTMLResponse
|
|
181
|
-
import winloop
|
|
188
|
+
import winloop
|
|
182
189
|
import uvicorn
|
|
183
|
-
import asyncio
|
|
184
|
-
import datetime
|
|
190
|
+
import asyncio
|
|
191
|
+
import datetime
|
|
185
192
|
|
|
186
193
|
app = FastAPI()
|
|
187
194
|
|
|
@@ -196,7 +203,7 @@ async def test_get_request():
|
|
|
196
203
|
return HTMLResponse("<html><body><h1>FAST API WORKS WITH WINLOOP!</h1></body></html>")
|
|
197
204
|
|
|
198
205
|
|
|
199
|
-
# starllete will use asyncio.to_thread() so that this can remain asynchronous
|
|
206
|
+
# starllete will use asyncio.to_thread() so that this can remain asynchronous
|
|
200
207
|
@app.get("/date")
|
|
201
208
|
def test_dynamic_response():
|
|
202
209
|
return str(datetime.datetime.now())
|
|
@@ -213,14 +220,14 @@ if __name__ == "__main__":
|
|
|
213
220
|
```
|
|
214
221
|
|
|
215
222
|
|
|
216
|
-
## How To Use Winloop When Uvloop is not
|
|
223
|
+
## How To Use Winloop When Uvloop is not available
|
|
217
224
|
|
|
218
225
|
```python
|
|
219
226
|
|
|
220
|
-
# Here's A small Example of using winloop when uvloop is not
|
|
227
|
+
# Here's A small Example of using winloop when uvloop is not available to us
|
|
221
228
|
import sys
|
|
222
229
|
import aiohttp
|
|
223
|
-
import asyncio
|
|
230
|
+
import asyncio
|
|
224
231
|
|
|
225
232
|
async def main():
|
|
226
233
|
async with aiohttp.ClientSession("https://httpbin.org") as client:
|
|
@@ -232,29 +239,34 @@ if __name__ == "__main__":
|
|
|
232
239
|
from winloop import run
|
|
233
240
|
else:
|
|
234
241
|
# if we're on apple or linux do this instead
|
|
235
|
-
from uvloop import run
|
|
242
|
+
from uvloop import run
|
|
236
243
|
run(main())
|
|
237
244
|
```
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
## Possible Upcomming Features/Optimizations to Winloop / This is also our TODO list
|
|
241
|
-
I have been looking deeply into some of the proposed Pulls and changes to `Uvloop` and I will be tuning in and listening to what's going on uvloop's end to see what we might have to change . This is a list of features I would like to implement from likely to least likely to be done as well as solved. If any of these feature have been added you will simply know by the fact that It won't be on this list anymore...
|
|
242
245
|
|
|
243
|
-
- Nightly Builds And Test Suite Workflows for anyone wanting to use newer unreleased versions.
|
|
244
246
|
|
|
245
|
-
|
|
247
|
+
## TODO-List
|
|
248
|
+
|
|
249
|
+
- Update Fastapi Example to a more recent version of fastapi
|
|
250
|
+
|
|
251
|
+
- Contact uvicorn about this [issue](https://github.com/Vizonex/Winloop/issues/11) I have a funny feeling something is going on here...
|
|
246
252
|
|
|
247
|
-
-
|
|
253
|
+
- Nightly Builds And Test Suite Workflows for anyone wanting to use newer unreleased versions.
|
|
248
254
|
|
|
249
255
|
- Drop All `DEF` Macros, I'm currently seeking help on replacements for macros where all the variables are known about at compile-time
|
|
250
256
|
|
|
251
|
-
- Adding in the
|
|
257
|
+
- Adding in the necessary hooks for pyinstaller to compile this fast library to executable code even though hooks have been known to inflate the size of the `.exe` files. This is because calling hidden-imports for all the `__init__.py` modules might annoy some developers. (Luckily I'm aware of this issue because I've been doing this myself...)
|
|
258
|
+
|
|
259
|
+
- write a workflow for compiling libuv on different versions of windows when distributing out pypi wheels.
|
|
252
260
|
|
|
253
|
-
-
|
|
261
|
+
- write a workflow for nightly builds if necessary for verification of pull requests.
|
|
254
262
|
|
|
255
|
-
- Sphinx Styled Documentation (Maybe I
|
|
263
|
+
- Sphinx Styled Documentation (Maybe I'm thinking about it...)
|
|
256
264
|
|
|
265
|
+
- Update benchmarks (They are old) can't believe I maintained this project for over a year now...
|
|
257
266
|
|
|
258
267
|
## Videos
|
|
259
268
|
- By me: https://www.youtube.com/watch?v=tz9RYJ6aBZ8 (I might make a tutorial on how to use and install winloop it for those who have reading problems)
|
|
260
|
-
- My Presentation and Virtual Confrence: https://www.youtube.com/watch?v=Cbb6trkKWXY
|
|
269
|
+
- My Presentation and Virtual Confrence: https://www.youtube.com/watch?v=Cbb6trkKWXY
|
|
270
|
+
|
|
271
|
+
## Contributing
|
|
272
|
+
I put my heart and soul into this library ever since it began and any help is apperciated and means a lot to me.
|
winloop-0.1.4/setup.py
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
vi = sys.version_info
|
|
4
|
+
if vi < (3, 8):
|
|
5
|
+
raise RuntimeError('winloop requires Python 3.8 or greater')
|
|
6
|
+
|
|
7
|
+
if sys.platform not in ('win32', 'cygwin', 'cli'):
|
|
8
|
+
raise RuntimeError('winloop only supports Windows at the moment,'
|
|
9
|
+
' install uvloop on Linux, MacOS, etc.')
|
|
10
|
+
|
|
11
|
+
from setuptools import Extension, setup, find_packages
|
|
12
|
+
import pathlib
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
from Cython.Build import cythonize
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
HERE = pathlib.Path("winloop")
|
|
19
|
+
_ROOT = pathlib.Path(__file__).parent
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def get_c_files():
|
|
23
|
+
path = pathlib.Path("vendor", "libuv", "src")
|
|
24
|
+
|
|
25
|
+
def c_files(p: pathlib.Path):
|
|
26
|
+
for i in p.iterdir():
|
|
27
|
+
if i.is_dir():
|
|
28
|
+
pass
|
|
29
|
+
if i.name.endswith(".c"):
|
|
30
|
+
yield i
|
|
31
|
+
|
|
32
|
+
for c in c_files(path):
|
|
33
|
+
yield c.as_posix()
|
|
34
|
+
for c in c_files(path / "win"):
|
|
35
|
+
yield c.as_posix()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# This is a temporary test solution and is not the official file yet but this
|
|
39
|
+
# is to display/show what I'm currently using to compile the winloop library...
|
|
40
|
+
try:
|
|
41
|
+
long_description = (HERE.parent / 'readme.md').open("r").read()
|
|
42
|
+
except Exception:
|
|
43
|
+
long_description = ""
|
|
44
|
+
|
|
45
|
+
# "Thank goodness we don't have to dig out the libpath ourselves I almost
|
|
46
|
+
# vomited" - Vizonex
|
|
47
|
+
Windows_Libraries = [
|
|
48
|
+
"Shell32.lib",
|
|
49
|
+
"Ws2_32.lib",
|
|
50
|
+
"Advapi32.lib",
|
|
51
|
+
"iphlpapi.lib",
|
|
52
|
+
"WSock32.lib",
|
|
53
|
+
"Userenv.lib",
|
|
54
|
+
"User32.lib",
|
|
55
|
+
"Dbghelp.lib",
|
|
56
|
+
"Ole32.lib"
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
c_files = list(get_c_files())
|
|
60
|
+
|
|
61
|
+
ext = [
|
|
62
|
+
Extension(
|
|
63
|
+
"winloop.loop",
|
|
64
|
+
["winloop\\loop.pyx"] + c_files,
|
|
65
|
+
include_dirs=["vendor/libuv/src", "vendor/libuv/src/win",
|
|
66
|
+
"vendor/libuv/include"],
|
|
67
|
+
# NOTE uv_a.lib will be user-compiled when
|
|
68
|
+
# I've fixed the install there's still been some problems with
|
|
69
|
+
# compiling fs-poll.c on it's own...
|
|
70
|
+
extra_link_args=Windows_Libraries,
|
|
71
|
+
# I have some macros setup for now to help me
|
|
72
|
+
# with debugging -Vizonex
|
|
73
|
+
library_dirs=["winloop"],
|
|
74
|
+
define_macros=[
|
|
75
|
+
("WIN32_LEAN_AND_MEAN", 1),
|
|
76
|
+
("_WIN32_WINNT", "0x0602")
|
|
77
|
+
]
|
|
78
|
+
)
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
with open(str(_ROOT / 'winloop' / '_version.py')) as f:
|
|
82
|
+
for line in f:
|
|
83
|
+
if line.startswith('__version__ ='):
|
|
84
|
+
_, _, version = line.partition('=')
|
|
85
|
+
VERSION = version.strip(" \n'\"")
|
|
86
|
+
break
|
|
87
|
+
else:
|
|
88
|
+
raise RuntimeError(
|
|
89
|
+
'unable to read the version from winloop/_version.py')
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
setup(
|
|
93
|
+
name="winloop",
|
|
94
|
+
author="Vizonex",
|
|
95
|
+
version=VERSION,
|
|
96
|
+
description="Windows version of uvloop",
|
|
97
|
+
ext_modules=cythonize(ext),
|
|
98
|
+
keywords=[
|
|
99
|
+
"winloop",
|
|
100
|
+
"libuv",
|
|
101
|
+
"windows",
|
|
102
|
+
"fast-asyncio",
|
|
103
|
+
"uvloop-alternative"
|
|
104
|
+
],
|
|
105
|
+
# Credit to godlygeek for helping me fix the setup.py file
|
|
106
|
+
packages=find_packages(include="winloop*"),
|
|
107
|
+
include_package_data=True,
|
|
108
|
+
long_description_content_type='text/markdown',
|
|
109
|
+
long_description=long_description,
|
|
110
|
+
classifiers=[
|
|
111
|
+
'License :: OSI Approved :: Apache Software License',
|
|
112
|
+
'License :: OSI Approved :: MIT License',
|
|
113
|
+
'Operating System :: Microsoft :: Windows',
|
|
114
|
+
'Programming Language :: Python :: 3.8',
|
|
115
|
+
'Programming Language :: Python :: 3.9',
|
|
116
|
+
'Programming Language :: Python :: 3.10',
|
|
117
|
+
'Programming Language :: Python :: 3.11',
|
|
118
|
+
'Programming Language :: Python :: 3.12',
|
|
119
|
+
'Intended Audience :: Developers',
|
|
120
|
+
'Framework :: AsyncIO'
|
|
121
|
+
]
|
|
122
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# NOTE: I forked the aiodns Repository you will have to use that for now
|
|
2
|
+
# or wait for the pull request I recently made to go through:
|
|
3
|
+
# https://github.com/saghul/aiodns/pull/116
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
import aiodns
|
|
7
|
+
except ImportError:
|
|
8
|
+
skip_tests = True
|
|
9
|
+
else:
|
|
10
|
+
skip_tests = False
|
|
11
|
+
|
|
12
|
+
import unittest
|
|
13
|
+
|
|
14
|
+
from winloop import _testbase as tb
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class _TestAiodns:
|
|
18
|
+
def test_dns_query(self):
|
|
19
|
+
# This is not allowed to fail...
|
|
20
|
+
resolver = aiodns.DNSResolver(loop=self.loop)
|
|
21
|
+
|
|
22
|
+
async def test():
|
|
23
|
+
async def query(name, query_type):
|
|
24
|
+
return await resolver.query(name, query_type)
|
|
25
|
+
await query('google.com', 'A')
|
|
26
|
+
await query('httpbin.org', 'A')
|
|
27
|
+
await query('example.com', 'A')
|
|
28
|
+
|
|
29
|
+
self.loop.run_until_complete(test())
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@unittest.skipIf(skip_tests, "no aiodns module")
|
|
33
|
+
class Test_UV_Aiodns(_TestAiodns, tb.UVTestCase):
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@unittest.skip("aiodns needs a SelectorEventLoop on Windows."
|
|
38
|
+
" See more: https://github.com/saghul/aiodns/issues/86")
|
|
39
|
+
class Test_AIO_Aiodns(_TestAiodns, tb.AIOTestCase):
|
|
40
|
+
pass
|
|
@@ -15,6 +15,7 @@ from winloop import _testbase as tb
|
|
|
15
15
|
|
|
16
16
|
# TODO: Fix or patch DeprecationWarning
|
|
17
17
|
|
|
18
|
+
|
|
18
19
|
class _TestAioHTTP:
|
|
19
20
|
|
|
20
21
|
def test_aiohttp_basic_1(self):
|
|
@@ -127,5 +128,6 @@ class Test_UV_AioHTTP(_TestAioHTTP, tb.UVTestCase):
|
|
|
127
128
|
class Test_AIO_AioHTTP(_TestAioHTTP, tb.AIOTestCase):
|
|
128
129
|
pass
|
|
129
130
|
|
|
131
|
+
|
|
130
132
|
if __name__ == "__main__":
|
|
131
133
|
unittest.main()
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
try:
|
|
2
|
-
import aiomultiprocess
|
|
2
|
+
import aiomultiprocess
|
|
3
|
+
import multiprocessing
|
|
3
4
|
except ImportError:
|
|
4
5
|
skip_tests = True
|
|
5
6
|
else:
|
|
@@ -8,26 +9,28 @@ import unittest
|
|
|
8
9
|
import winloop
|
|
9
10
|
import random
|
|
10
11
|
import asyncio
|
|
11
|
-
import os
|
|
12
12
|
from winloop import _testbase as tb
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
async def test_func(sleep: float):
|
|
16
|
-
return await asyncio.sleep(sleep)
|
|
16
|
+
return await asyncio.sleep(sleep)
|
|
17
|
+
|
|
17
18
|
|
|
18
19
|
def my_map():
|
|
19
20
|
return [random.uniform(0.005, 1) for _ in range(7)]
|
|
20
21
|
|
|
22
|
+
|
|
21
23
|
class _Test_Multiprocessing():
|
|
22
24
|
"""Used for Testing aiomultiprocessing"""
|
|
23
25
|
|
|
24
26
|
def test_proccess_spawning(self):
|
|
25
|
-
|
|
26
|
-
# See:
|
|
27
|
+
|
|
28
|
+
# See:
|
|
29
|
+
# https://github.com/Vizonex/Winloop/issues/11#issuecomment-1922659521
|
|
27
30
|
self.processes = set()
|
|
28
31
|
# There must be at least 2 pids setup for this to be correctly ran...
|
|
29
32
|
total_proccesses = 2
|
|
30
|
-
|
|
33
|
+
|
|
31
34
|
async def test():
|
|
32
35
|
async with aiomultiprocess.Pool(total_proccesses) as pool:
|
|
33
36
|
self.processes.update(p.pid for p in pool.processes)
|
|
@@ -36,8 +39,6 @@ class _Test_Multiprocessing():
|
|
|
36
39
|
self.assertEqual(len(self.processes), total_proccesses)
|
|
37
40
|
|
|
38
41
|
self.loop.run_until_complete(test())
|
|
39
|
-
|
|
40
|
-
|
|
41
42
|
|
|
42
43
|
|
|
43
44
|
@unittest.skipIf(skip_tests, "no aiomultiproccess module")
|
|
@@ -51,10 +52,9 @@ class Test_AIO_AioMultiprocess(_Test_Multiprocessing, tb.AIOTestCase):
|
|
|
51
52
|
|
|
52
53
|
|
|
53
54
|
if __name__ == "__main__":
|
|
54
|
-
# I have confirmed that multiproccessing is supported so no need
|
|
55
|
+
# I have confirmed that multiproccessing is supported so no need
|
|
56
|
+
# to continue with trying... - Vizonex...
|
|
55
57
|
multiprocessing.freeze_support()
|
|
56
58
|
# aiomultiprocess.set_start_method("spawn")
|
|
57
59
|
winloop.install()
|
|
58
60
|
unittest.main()
|
|
59
|
-
|
|
60
|
-
|