winloop 0.1.1__tar.gz → 0.1.3__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.1/winloop.egg-info → winloop-0.1.3}/PKG-INFO +36 -26
- {winloop-0.1.1 → winloop-0.1.3}/README.md +35 -25
- {winloop-0.1.1 → winloop-0.1.3}/setup.py +11 -2
- winloop-0.1.3/tests/__init__.py +1 -0
- winloop-0.1.3/tests/__main__.py +16 -0
- winloop-0.1.3/tests/test_aiodns.py +41 -0
- winloop-0.1.3/tests/test_aiohttp.py +131 -0
- winloop-0.1.3/tests/test_aiomultiprocess.py +60 -0
- winloop-0.1.3/tests/test_cython.py +32 -0
- winloop-0.1.3/tests/test_executors.py +43 -0
- {winloop-0.1.1 → winloop-0.1.3}/winloop/__init__.py +35 -49
- {winloop-0.1.1 → winloop-0.1.3}/winloop/_testbase.py +85 -87
- winloop-0.1.3/winloop/_version.py +13 -0
- {winloop-0.1.1 → winloop-0.1.3}/winloop/loop.c +7492 -7425
- {winloop-0.1.1 → winloop-0.1.3}/winloop/loop.pyi +26 -11
- {winloop-0.1.1 → winloop-0.1.3/winloop.egg-info}/PKG-INFO +36 -26
- {winloop-0.1.1 → winloop-0.1.3}/winloop.egg-info/SOURCES.txt +8 -0
- {winloop-0.1.1 → winloop-0.1.3}/winloop.egg-info/top_level.txt +1 -0
- {winloop-0.1.1 → winloop-0.1.3}/LICENSE-APACHE +0 -0
- {winloop-0.1.1 → winloop-0.1.3}/LICENSE-MIT +0 -0
- {winloop-0.1.1 → winloop-0.1.3}/pyproject.toml +0 -0
- {winloop-0.1.1 → winloop-0.1.3}/setup.cfg +0 -0
- {winloop-0.1.1 → winloop-0.1.3}/winloop/_noop.py +0 -0
- {winloop-0.1.1 → winloop-0.1.3}/winloop/includes/__init__.py +0 -0
- {winloop-0.1.1 → winloop-0.1.3}/winloop/includes/context.h +0 -0
- {winloop-0.1.1 → winloop-0.1.3}/winloop.egg-info/dependency_links.txt +0 -0
- {winloop-0.1.1 → winloop-0.1.3}/winloop.egg-info/requires.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: winloop
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: An alternative library for uvloop compatibility with Windows
|
|
5
5
|
Author: Vizonex
|
|
6
6
|
License: MIT
|
|
@@ -17,32 +17,42 @@ License-File: LICENSE-MIT
|
|
|
17
17
|
Requires-Dist: cython
|
|
18
18
|
|
|
19
19
|
<img src="https://raw.githubusercontent.com/Vizonex/Winloop/main/winloop.png" width="200px"/>
|
|
20
|
+
<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
21
|
|
|
21
22
|
# Winloop
|
|
22
|
-
An Alternative library for uvloop compatability with windows because let's face it. Window's python asyncio is garabage escpecially when Windows Defender
|
|
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 avalible
|
|
23
|
+
An Alternative library for uvloop compatability 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.
|
|
24
|
+
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 avalible for windows [but windows was never compatable with uvloop.](https://github.com/MagicStack/uvloop/issues/14#issuecomment-575826367])
|
|
24
25
|
|
|
25
|
-
Because nobody was willing to step in after so many years of
|
|
26
|
+
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 compatable by carefully removing and changing parts that were not made for windows. Many hours of research went into making this library exist.
|
|
26
27
|
|
|
27
|
-
The differences with __uvloop__ is that forking has been fully disabled and some smaller api calls had to be changed
|
|
28
|
+
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
29
|
|
|
30
|
+
There is a perfromance 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 performace to it's brother uvloop.
|
|
29
31
|
|
|
30
|
-
There is a perfromance 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 those ssl problem as well.
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
## How to install Winloop on your Operating System
|
|
33
|
+
## How to install Winloop on your Windows Operating System
|
|
34
34
|
|
|
35
35
|
```
|
|
36
36
|
pip install winloop
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
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
|
|
40
|
+
to compile this library on your own.
|
|
40
41
|
|
|
41
42
|
```
|
|
42
43
|
python setup.py build_ext --inplace
|
|
43
44
|
```
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
## Issues Reporting
|
|
47
|
+
|
|
48
|
+
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.
|
|
49
|
+
|
|
50
|
+
## Making pull requests
|
|
51
|
+
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.
|
|
52
|
+
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.
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
46
56
|
|
|
47
57
|
```python
|
|
48
58
|
try:
|
|
@@ -243,37 +253,37 @@ async def main():
|
|
|
243
253
|
|
|
244
254
|
if __name__ == "__main__":
|
|
245
255
|
if sys.platform in ('win32', 'cygwin', 'cli'):
|
|
246
|
-
from winloop import
|
|
256
|
+
from winloop import run
|
|
247
257
|
else:
|
|
248
258
|
# if we're on apple or linux do this instead
|
|
249
|
-
from uvloop import
|
|
250
|
-
|
|
251
|
-
asyncio.run(main())
|
|
259
|
+
from uvloop import run
|
|
260
|
+
run(main())
|
|
252
261
|
```
|
|
253
262
|
|
|
254
263
|
|
|
255
|
-
##
|
|
256
|
-
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...
|
|
264
|
+
## TODO-List
|
|
257
265
|
|
|
258
|
-
-
|
|
259
|
-
|
|
260
|
-
- Make a sucessful Github Workflow for uploading wheels to pypi any help and guidence would be appreciated
|
|
266
|
+
- Update Fastapi Example to a more recent version of fastapi
|
|
261
267
|
|
|
262
|
-
-
|
|
268
|
+
- Contact uvicorn about this [issue](https://github.com/Vizonex/Winloop/issues/11) I have a funny feeling something is going on here...
|
|
263
269
|
|
|
264
|
-
-
|
|
270
|
+
- Nightly Builds And Test Suite Workflows for anyone wanting to use newer unreleased versions.
|
|
265
271
|
|
|
266
|
-
- Drop
|
|
272
|
+
- Drop All `DEF` Macros, I'm currently seeking help on replacements for macros where all the variables are known about at compile-time
|
|
267
273
|
|
|
268
|
-
-
|
|
274
|
+
- Adding in the nessesary 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...)
|
|
269
275
|
|
|
270
|
-
-
|
|
276
|
+
- write a workflow for compiling libuv on different versions of windows when distributing out pypi wheels.
|
|
271
277
|
|
|
272
|
-
-
|
|
278
|
+
- write a workflow for nightly builds if nessesary for verification of pull requests.
|
|
273
279
|
|
|
274
|
-
-
|
|
280
|
+
- Sphinx Styled Documentation (Maybe I'm thinking about it...)
|
|
275
281
|
|
|
282
|
+
- Update benchmarks (They are old) can't belive I maintained this project for over a year now...
|
|
276
283
|
|
|
277
284
|
## Videos
|
|
278
285
|
- 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)
|
|
279
286
|
- My Presentation and Virtual Confrence: https://www.youtube.com/watch?v=Cbb6trkKWXY
|
|
287
|
+
|
|
288
|
+
## Contributing
|
|
289
|
+
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,30 +1,40 @@
|
|
|
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 compatability with windows because let's face it. Window's python asyncio is garabage escpecially when Windows Defender
|
|
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 avalible
|
|
5
|
+
An Alternative library for uvloop compatability 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 avalible for windows [but windows was never compatable 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
|
|
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 compatable 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
|
-
The differences with __uvloop__ is that forking has been fully disabled and some smaller api calls had to be changed
|
|
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
|
|
|
12
|
+
There is a perfromance 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 performace to it's brother uvloop.
|
|
11
13
|
|
|
12
|
-
There is a perfromance 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 those ssl problem as well.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
## How to install Winloop on your Operating System
|
|
15
|
+
## How to install Winloop on your Windows Operating System
|
|
16
16
|
|
|
17
17
|
```
|
|
18
18
|
pip install winloop
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
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
|
|
22
|
+
to compile this library on your own.
|
|
22
23
|
|
|
23
24
|
```
|
|
24
25
|
python setup.py build_ext --inplace
|
|
25
26
|
```
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
## Issues Reporting
|
|
29
|
+
|
|
30
|
+
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.
|
|
31
|
+
|
|
32
|
+
## Making pull requests
|
|
33
|
+
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.
|
|
34
|
+
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.
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
28
38
|
|
|
29
39
|
```python
|
|
30
40
|
try:
|
|
@@ -225,37 +235,37 @@ async def main():
|
|
|
225
235
|
|
|
226
236
|
if __name__ == "__main__":
|
|
227
237
|
if sys.platform in ('win32', 'cygwin', 'cli'):
|
|
228
|
-
from winloop import
|
|
238
|
+
from winloop import run
|
|
229
239
|
else:
|
|
230
240
|
# if we're on apple or linux do this instead
|
|
231
|
-
from uvloop import
|
|
232
|
-
|
|
233
|
-
asyncio.run(main())
|
|
241
|
+
from uvloop import run
|
|
242
|
+
run(main())
|
|
234
243
|
```
|
|
235
244
|
|
|
236
245
|
|
|
237
|
-
##
|
|
238
|
-
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...
|
|
246
|
+
## TODO-List
|
|
239
247
|
|
|
240
|
-
-
|
|
241
|
-
|
|
242
|
-
- Make a sucessful Github Workflow for uploading wheels to pypi any help and guidence would be appreciated
|
|
248
|
+
- Update Fastapi Example to a more recent version of fastapi
|
|
243
249
|
|
|
244
|
-
-
|
|
250
|
+
- Contact uvicorn about this [issue](https://github.com/Vizonex/Winloop/issues/11) I have a funny feeling something is going on here...
|
|
245
251
|
|
|
246
|
-
-
|
|
252
|
+
- Nightly Builds And Test Suite Workflows for anyone wanting to use newer unreleased versions.
|
|
247
253
|
|
|
248
|
-
- Drop
|
|
254
|
+
- Drop All `DEF` Macros, I'm currently seeking help on replacements for macros where all the variables are known about at compile-time
|
|
249
255
|
|
|
250
|
-
-
|
|
256
|
+
- Adding in the nessesary 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...)
|
|
251
257
|
|
|
252
|
-
-
|
|
258
|
+
- write a workflow for compiling libuv on different versions of windows when distributing out pypi wheels.
|
|
253
259
|
|
|
254
|
-
-
|
|
260
|
+
- write a workflow for nightly builds if nessesary for verification of pull requests.
|
|
255
261
|
|
|
256
|
-
-
|
|
262
|
+
- Sphinx Styled Documentation (Maybe I'm thinking about it...)
|
|
257
263
|
|
|
264
|
+
- Update benchmarks (They are old) can't belive I maintained this project for over a year now...
|
|
258
265
|
|
|
259
266
|
## Videos
|
|
260
267
|
- 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)
|
|
261
268
|
- My Presentation and Virtual Confrence: https://www.youtube.com/watch?v=Cbb6trkKWXY
|
|
269
|
+
|
|
270
|
+
## Contributing
|
|
271
|
+
I put my heart and soul into this library ever since it began and any help is apperciated and means a lot to me.
|
|
@@ -7,9 +7,18 @@ from Cython.Build import cythonize
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
HERE = pathlib.Path("winloop")
|
|
10
|
+
_ROOT = pathlib.Path(__file__).parent
|
|
10
11
|
|
|
11
|
-
__version__ = "0.1.1"
|
|
12
12
|
|
|
13
|
+
with open(str(_ROOT / 'winloop' / '_version.py')) as f:
|
|
14
|
+
for line in f:
|
|
15
|
+
if line.startswith('__version__ ='):
|
|
16
|
+
_, _, version = line.partition('=')
|
|
17
|
+
VERSION = version.strip(" \n'\"")
|
|
18
|
+
break
|
|
19
|
+
else:
|
|
20
|
+
raise RuntimeError(
|
|
21
|
+
'unable to read the version from winloop/_version.py')
|
|
13
22
|
|
|
14
23
|
|
|
15
24
|
# This is a temporary test Solution and is not the official file yet but this is to display/show what
|
|
@@ -54,7 +63,7 @@ def do_installation():
|
|
|
54
63
|
setup(
|
|
55
64
|
name="winloop",
|
|
56
65
|
author="Vizonex",
|
|
57
|
-
version=
|
|
66
|
+
version=VERSION,
|
|
58
67
|
description="""An alternative library for uvloop compatibility with Windows""",
|
|
59
68
|
ext_modules=cythonize(ext),
|
|
60
69
|
license="MIT",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# It's just here as a stub...
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import os.path
|
|
2
|
+
import sys
|
|
3
|
+
import unittest
|
|
4
|
+
import unittest.runner
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def suite():
|
|
8
|
+
test_loader = unittest.TestLoader()
|
|
9
|
+
test_suite = test_loader.discover(os.path.dirname(__file__))
|
|
10
|
+
return test_suite
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
if __name__ == '__main__':
|
|
14
|
+
runner = unittest.runner.TextTestRunner()
|
|
15
|
+
result = runner.run(suite())
|
|
16
|
+
sys.exit(not result.wasSuccessful())
|
|
@@ -0,0 +1,41 @@
|
|
|
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: https://github.com/saghul/aiodns/pull/116
|
|
3
|
+
|
|
4
|
+
try:
|
|
5
|
+
import aiodns
|
|
6
|
+
except ImportError:
|
|
7
|
+
skip_tests = True
|
|
8
|
+
else:
|
|
9
|
+
skip_tests = False
|
|
10
|
+
|
|
11
|
+
import asyncio
|
|
12
|
+
import sys
|
|
13
|
+
import unittest
|
|
14
|
+
import weakref
|
|
15
|
+
|
|
16
|
+
from winloop import _testbase as tb
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class _TestAiodns:
|
|
20
|
+
def test_dns_query(self):
|
|
21
|
+
# This is not allowed to fail...
|
|
22
|
+
resolver = aiodns.DNSResolver(loop=self.loop)
|
|
23
|
+
|
|
24
|
+
async def test():
|
|
25
|
+
async def query(name, query_type):
|
|
26
|
+
return await resolver.query(name, query_type)
|
|
27
|
+
await query('google.com', 'A')
|
|
28
|
+
await query('httpbin.org', 'A')
|
|
29
|
+
await query('example.com', 'A')
|
|
30
|
+
|
|
31
|
+
self.loop.run_until_complete(test())
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@unittest.skipIf(skip_tests, "no aiodns module")
|
|
35
|
+
class Test_UV_Aiodns(_TestAiodns, tb.UVTestCase):
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@unittest.skip("aiodns needs a SelectorEventLoop on Windows. See more: https://github.com/saghul/aiodns/issues/86")
|
|
40
|
+
class Test_AIO_Aiodns(_TestAiodns, tb.AIOTestCase):
|
|
41
|
+
pass
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
try:
|
|
2
|
+
import aiohttp
|
|
3
|
+
import aiohttp.web
|
|
4
|
+
except ImportError:
|
|
5
|
+
skip_tests = True
|
|
6
|
+
else:
|
|
7
|
+
skip_tests = False
|
|
8
|
+
|
|
9
|
+
import asyncio
|
|
10
|
+
import sys
|
|
11
|
+
import unittest
|
|
12
|
+
import weakref
|
|
13
|
+
|
|
14
|
+
from winloop import _testbase as tb
|
|
15
|
+
|
|
16
|
+
# TODO: Fix or patch DeprecationWarning
|
|
17
|
+
|
|
18
|
+
class _TestAioHTTP:
|
|
19
|
+
|
|
20
|
+
def test_aiohttp_basic_1(self):
|
|
21
|
+
|
|
22
|
+
PAYLOAD = '<h1>It Works!</h1>' * 10000
|
|
23
|
+
|
|
24
|
+
async def on_request(request):
|
|
25
|
+
return aiohttp.web.Response(text=PAYLOAD)
|
|
26
|
+
|
|
27
|
+
asyncio.set_event_loop(self.loop)
|
|
28
|
+
app = aiohttp.web.Application()
|
|
29
|
+
app.router.add_get('/', on_request)
|
|
30
|
+
|
|
31
|
+
runner = aiohttp.web.AppRunner(app)
|
|
32
|
+
self.loop.run_until_complete(runner.setup())
|
|
33
|
+
site = aiohttp.web.TCPSite(runner, '0.0.0.0', '0')
|
|
34
|
+
self.loop.run_until_complete(site.start())
|
|
35
|
+
port = site._server.sockets[0].getsockname()[1]
|
|
36
|
+
|
|
37
|
+
async def test():
|
|
38
|
+
# Make sure we're using the correct event loop.
|
|
39
|
+
self.assertIs(asyncio.get_event_loop(), self.loop)
|
|
40
|
+
|
|
41
|
+
for addr in (('localhost', port),
|
|
42
|
+
('127.0.0.1', port)):
|
|
43
|
+
async with aiohttp.ClientSession() as client:
|
|
44
|
+
async with client.get('http://{}:{}'.format(*addr)) as r:
|
|
45
|
+
self.assertEqual(r.status, 200)
|
|
46
|
+
result = await r.text()
|
|
47
|
+
self.assertEqual(result, PAYLOAD)
|
|
48
|
+
|
|
49
|
+
self.loop.run_until_complete(test())
|
|
50
|
+
self.loop.run_until_complete(runner.cleanup())
|
|
51
|
+
|
|
52
|
+
def test_aiohttp_graceful_shutdown(self):
|
|
53
|
+
# NOTE: This Might Already be solved I haven't checked yet - Vizonex
|
|
54
|
+
if self.implementation == 'asyncio' and sys.version_info >= (3, 12, 0):
|
|
55
|
+
# In Python 3.12.0, asyncio.Server.wait_closed() waits for all
|
|
56
|
+
# existing connections to complete, before aiohttp sends
|
|
57
|
+
# on_shutdown signals.
|
|
58
|
+
# https://github.com/aio-libs/aiohttp/issues/7675#issuecomment-1752143748
|
|
59
|
+
# https://github.com/python/cpython/pull/98582
|
|
60
|
+
raise unittest.SkipTest('bug in aiohttp: #7675')
|
|
61
|
+
|
|
62
|
+
async def websocket_handler(request):
|
|
63
|
+
ws = aiohttp.web.WebSocketResponse()
|
|
64
|
+
await ws.prepare(request)
|
|
65
|
+
request.app['websockets'].add(ws)
|
|
66
|
+
try:
|
|
67
|
+
async for msg in ws:
|
|
68
|
+
await ws.send_str(msg.data)
|
|
69
|
+
finally:
|
|
70
|
+
request.app['websockets'].discard(ws)
|
|
71
|
+
return ws
|
|
72
|
+
|
|
73
|
+
async def on_shutdown(app):
|
|
74
|
+
for ws in set(app['websockets']):
|
|
75
|
+
await ws.close(
|
|
76
|
+
code=aiohttp.WSCloseCode.GOING_AWAY,
|
|
77
|
+
message='Server shutdown')
|
|
78
|
+
|
|
79
|
+
asyncio.set_event_loop(self.loop)
|
|
80
|
+
app = aiohttp.web.Application()
|
|
81
|
+
app.router.add_get('/', websocket_handler)
|
|
82
|
+
app.on_shutdown.append(on_shutdown)
|
|
83
|
+
app['websockets'] = weakref.WeakSet()
|
|
84
|
+
|
|
85
|
+
runner = aiohttp.web.AppRunner(app)
|
|
86
|
+
self.loop.run_until_complete(runner.setup())
|
|
87
|
+
site = aiohttp.web.TCPSite(
|
|
88
|
+
runner,
|
|
89
|
+
'0.0.0.0',
|
|
90
|
+
0,
|
|
91
|
+
# https://github.com/aio-libs/aiohttp/pull/7188
|
|
92
|
+
shutdown_timeout=0.1,
|
|
93
|
+
)
|
|
94
|
+
self.loop.run_until_complete(site.start())
|
|
95
|
+
port = site._server.sockets[0].getsockname()[1]
|
|
96
|
+
|
|
97
|
+
async def client():
|
|
98
|
+
async with aiohttp.ClientSession() as client:
|
|
99
|
+
async with client.ws_connect(
|
|
100
|
+
'http://127.0.0.1:{}'.format(port)) as ws:
|
|
101
|
+
await ws.send_str("hello")
|
|
102
|
+
async for msg in ws:
|
|
103
|
+
assert msg.data == "hello"
|
|
104
|
+
|
|
105
|
+
client_task = asyncio.ensure_future(client())
|
|
106
|
+
|
|
107
|
+
async def stop():
|
|
108
|
+
await asyncio.sleep(0.1)
|
|
109
|
+
try:
|
|
110
|
+
await asyncio.wait_for(runner.cleanup(), timeout=0.5)
|
|
111
|
+
finally:
|
|
112
|
+
try:
|
|
113
|
+
client_task.cancel()
|
|
114
|
+
await client_task
|
|
115
|
+
except asyncio.CancelledError:
|
|
116
|
+
pass
|
|
117
|
+
|
|
118
|
+
self.loop.run_until_complete(stop())
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@unittest.skipIf(skip_tests, "no aiohttp module")
|
|
122
|
+
class Test_UV_AioHTTP(_TestAioHTTP, tb.UVTestCase):
|
|
123
|
+
pass
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@unittest.skipIf(skip_tests, "no aiohttp module")
|
|
127
|
+
class Test_AIO_AioHTTP(_TestAioHTTP, tb.AIOTestCase):
|
|
128
|
+
pass
|
|
129
|
+
|
|
130
|
+
if __name__ == "__main__":
|
|
131
|
+
unittest.main()
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
try:
|
|
2
|
+
import aiomultiprocess, multiprocessing
|
|
3
|
+
except ImportError:
|
|
4
|
+
skip_tests = True
|
|
5
|
+
else:
|
|
6
|
+
skip_tests = False
|
|
7
|
+
import unittest
|
|
8
|
+
import winloop
|
|
9
|
+
import random
|
|
10
|
+
import asyncio
|
|
11
|
+
import os
|
|
12
|
+
from winloop import _testbase as tb
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
async def test_func(sleep: float):
|
|
16
|
+
return await asyncio.sleep(sleep)
|
|
17
|
+
|
|
18
|
+
def my_map():
|
|
19
|
+
return [random.uniform(0.005, 1) for _ in range(7)]
|
|
20
|
+
|
|
21
|
+
class _Test_Multiprocessing():
|
|
22
|
+
"""Used for Testing aiomultiprocessing"""
|
|
23
|
+
|
|
24
|
+
def test_proccess_spawning(self):
|
|
25
|
+
|
|
26
|
+
# See: https://github.com/Vizonex/Winloop/issues/11#issuecomment-1922659521
|
|
27
|
+
self.processes = set()
|
|
28
|
+
# There must be at least 2 pids setup for this to be correctly ran...
|
|
29
|
+
total_proccesses = 2
|
|
30
|
+
|
|
31
|
+
async def test():
|
|
32
|
+
async with aiomultiprocess.Pool(total_proccesses) as pool:
|
|
33
|
+
self.processes.update(p.pid for p in pool.processes)
|
|
34
|
+
await pool.map(test_func, my_map())
|
|
35
|
+
await asyncio.sleep(0.005)
|
|
36
|
+
self.assertEqual(len(self.processes), total_proccesses)
|
|
37
|
+
|
|
38
|
+
self.loop.run_until_complete(test())
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@unittest.skipIf(skip_tests, "no aiomultiproccess module")
|
|
44
|
+
class Test_UV_AioMultiprocess(_Test_Multiprocessing, tb.UVTestCase):
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@unittest.skipIf(skip_tests, "no aiomultiproccess module")
|
|
49
|
+
class Test_AIO_AioMultiprocess(_Test_Multiprocessing, tb.AIOTestCase):
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
if __name__ == "__main__":
|
|
54
|
+
# I have confirmed that multiproccessing is supported so no need to continue with trying... - Vizonex...
|
|
55
|
+
multiprocessing.freeze_support()
|
|
56
|
+
# aiomultiprocess.set_start_method("spawn")
|
|
57
|
+
winloop.install()
|
|
58
|
+
unittest.main()
|
|
59
|
+
|
|
60
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from winloop._testbase import UVTestCase
|
|
3
|
+
|
|
4
|
+
class TestCythonIntegration(UVTestCase):
|
|
5
|
+
def test_cython_coro_is_coroutine(self):
|
|
6
|
+
from winloop.loop import _test_coroutine_1
|
|
7
|
+
from asyncio.coroutines import _format_coroutine
|
|
8
|
+
|
|
9
|
+
coro = _test_coroutine_1()
|
|
10
|
+
|
|
11
|
+
coro_fmt = _format_coroutine(coro)
|
|
12
|
+
self.assertTrue(
|
|
13
|
+
coro_fmt.startswith("_test_coroutine_1() done")
|
|
14
|
+
or coro_fmt.startswith("_test_coroutine_1() running")
|
|
15
|
+
)
|
|
16
|
+
self.assertEqual(_test_coroutine_1.__qualname__, "_test_coroutine_1")
|
|
17
|
+
self.assertEqual(_test_coroutine_1.__name__, "_test_coroutine_1")
|
|
18
|
+
self.assertTrue(asyncio.iscoroutine(coro))
|
|
19
|
+
fut = asyncio.ensure_future(coro)
|
|
20
|
+
self.assertTrue(isinstance(fut, asyncio.Future))
|
|
21
|
+
self.assertTrue(isinstance(fut, asyncio.Task))
|
|
22
|
+
fut.cancel()
|
|
23
|
+
|
|
24
|
+
with self.assertRaises(asyncio.CancelledError):
|
|
25
|
+
self.loop.run_until_complete(fut)
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
_format_coroutine(coro) # This line checks against Cython segfault
|
|
29
|
+
except TypeError:
|
|
30
|
+
# TODO: Fix Cython to not reset __name__/__qualname__ to None
|
|
31
|
+
pass
|
|
32
|
+
coro.close()
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import concurrent.futures
|
|
3
|
+
import multiprocessing
|
|
4
|
+
import unittest
|
|
5
|
+
|
|
6
|
+
from winloop import _testbase as tb
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def fib(n):
|
|
10
|
+
if n < 2:
|
|
11
|
+
return 1
|
|
12
|
+
return fib(n - 2) + fib(n - 1)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class _TestExecutors:
|
|
16
|
+
def run_pool_test(self, pool_factory):
|
|
17
|
+
async def run():
|
|
18
|
+
pool = pool_factory()
|
|
19
|
+
with pool:
|
|
20
|
+
coros = []
|
|
21
|
+
for i in range(0, 10):
|
|
22
|
+
coros.append(self.loop.run_in_executor(pool, fib, i))
|
|
23
|
+
res = await asyncio.gather(*coros)
|
|
24
|
+
self.assertEqual(res, fib10)
|
|
25
|
+
await asyncio.sleep(0.01)
|
|
26
|
+
|
|
27
|
+
fib10 = [fib(i) for i in range(10)]
|
|
28
|
+
self.loop.run_until_complete(run())
|
|
29
|
+
|
|
30
|
+
# Proccess Pool Works just fine...
|
|
31
|
+
def test_executors_process_pool_01(self):
|
|
32
|
+
self.run_pool_test(concurrent.futures.ProcessPoolExecutor)
|
|
33
|
+
|
|
34
|
+
def test_executors_process_pool_02(self):
|
|
35
|
+
self.run_pool_test(concurrent.futures.ThreadPoolExecutor)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class TestUVExecutors(_TestExecutors, tb.UVTestCase):
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class TestAIOExecutors(_TestExecutors, tb.AIOTestCase):
|
|
43
|
+
pass
|