PyChannel 0.1.0__tar.gz → 1.5__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.
- {pychannel-0.1.0 → pychannel-1.5}/PKG-INFO +8 -4
- {pychannel-0.1.0 → pychannel-1.5}/PyChannel/__init__.py +1 -1
- {pychannel-0.1.0 → pychannel-1.5}/PyChannel/task.py +51 -7
- {pychannel-0.1.0 → pychannel-1.5}/PyChannel.egg-info/PKG-INFO +8 -4
- {pychannel-0.1.0 → pychannel-1.5}/README.md +5 -3
- {pychannel-0.1.0 → pychannel-1.5}/pyproject.toml +4 -2
- {pychannel-0.1.0 → pychannel-1.5}/PyChannel/buffer.py +0 -0
- {pychannel-0.1.0 → pychannel-1.5}/PyChannel/channel.py +0 -0
- {pychannel-0.1.0 → pychannel-1.5}/PyChannel/global_logs.py +0 -0
- {pychannel-0.1.0 → pychannel-1.5}/PyChannel.egg-info/SOURCES.txt +0 -0
- {pychannel-0.1.0 → pychannel-1.5}/PyChannel.egg-info/dependency_links.txt +0 -0
- {pychannel-0.1.0 → pychannel-1.5}/PyChannel.egg-info/requires.txt +0 -0
- {pychannel-0.1.0 → pychannel-1.5}/PyChannel.egg-info/top_level.txt +0 -0
- {pychannel-0.1.0 → pychannel-1.5}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyChannel
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.5
|
|
4
4
|
Summary: A Python concurrency library inspired by Go's goroutines and channels
|
|
5
5
|
Author: Brayan
|
|
6
6
|
Keywords: concurrency,channels,goroutines,parallelism,multiprocessing
|
|
@@ -11,8 +11,10 @@ Classifier: Programming Language :: Python :: 3
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
16
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
-
Requires-Python:
|
|
17
|
+
Requires-Python: >=3.10
|
|
16
18
|
Description-Content-Type: text/markdown
|
|
17
19
|
Requires-Dist: loky<4,>=3.5.6
|
|
18
20
|
Provides-Extra: dev
|
|
@@ -22,8 +24,8 @@ Requires-Dist: twine>=6.1; extra == "dev"
|
|
|
22
24
|
|
|
23
25
|
# PyChannel
|
|
24
26
|
|
|
25
|
-

|
|
28
|
+

|
|
27
29
|

|
|
28
30
|

|
|
29
31
|
|
|
@@ -108,6 +110,8 @@ resultado = channel.get() # 100
|
|
|
108
110
|
|
|
109
111
|
Se a função gerar uma exceção, ela permanece armazenada no `Future`. Quando existe um Channel, o objeto da exceção também é enviado para ele.
|
|
110
112
|
|
|
113
|
+
Os executores registrados pela `Task` são finalizados automaticamente quando o programa termina. Quando for necessário encerrar o pool antes do fim do programa, use `task.shutdown()`.
|
|
114
|
+
|
|
111
115
|
## `Channel`
|
|
112
116
|
|
|
113
117
|
O `Channel` transporta valores entre produtores e consumidores por meio de uma `multiprocessing.Queue`.
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import atexit
|
|
2
|
+
import logging
|
|
3
|
+
from threading import Lock
|
|
2
4
|
from concurrent.futures import Future
|
|
3
5
|
from functools import wraps
|
|
4
6
|
from typing import Any
|
|
@@ -10,7 +12,44 @@ from PyChannel.buffer import Buffer
|
|
|
10
12
|
from PyChannel.channel import Channel
|
|
11
13
|
|
|
12
14
|
#Pega a configuração de logs
|
|
13
|
-
logger = logging.getLogger(__name__)
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
_executors = []
|
|
18
|
+
_executors_lock = Lock()
|
|
19
|
+
_cleanup_registered = False
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _shutdown_executors() -> None:
|
|
23
|
+
"""Finaliza executores e o ResourceTracker do loky ao encerrar o Python."""
|
|
24
|
+
with _executors_lock:
|
|
25
|
+
executors = _executors.copy()
|
|
26
|
+
|
|
27
|
+
for executor in executors:
|
|
28
|
+
try:
|
|
29
|
+
executor.shutdown(wait=True)
|
|
30
|
+
except Exception:
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
# O loky 3.5.6 pode deixar o ResourceTracker para o destrutor do Python,
|
|
34
|
+
# que falha em algumas versões recentes do Python no Windows.
|
|
35
|
+
try:
|
|
36
|
+
from loky.backend import resource_tracker
|
|
37
|
+
|
|
38
|
+
resource_tracker._resource_tracker._stop()
|
|
39
|
+
except Exception:
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _register_executor(executor) -> None:
|
|
44
|
+
global _cleanup_registered
|
|
45
|
+
|
|
46
|
+
with _executors_lock:
|
|
47
|
+
if not any(registered is executor for registered in _executors):
|
|
48
|
+
_executors.append(executor)
|
|
49
|
+
|
|
50
|
+
if not _cleanup_registered:
|
|
51
|
+
atexit.register(_shutdown_executors)
|
|
52
|
+
_cleanup_registered = True
|
|
14
53
|
|
|
15
54
|
#Cria tasks
|
|
16
55
|
class Task:
|
|
@@ -22,9 +61,10 @@ class Task:
|
|
|
22
61
|
buffer: Buffer = None,
|
|
23
62
|
) -> None:
|
|
24
63
|
self.name = name if name is not None else "task"
|
|
25
|
-
self.ch = channel
|
|
26
|
-
self.buff = buffer
|
|
27
|
-
self.process = get_reusable_executor(max_workers=max_workers)
|
|
64
|
+
self.ch = channel
|
|
65
|
+
self.buff = buffer
|
|
66
|
+
self.process = get_reusable_executor(max_workers=max_workers)
|
|
67
|
+
_register_executor(self.process)
|
|
28
68
|
|
|
29
69
|
def _finished(self, future: Future[Any]) -> None:
|
|
30
70
|
try:
|
|
@@ -51,7 +91,7 @@ class Task:
|
|
|
51
91
|
if self.ch is not None:
|
|
52
92
|
self.ch.send(result=output)
|
|
53
93
|
|
|
54
|
-
def run(self):
|
|
94
|
+
def run(self):
|
|
55
95
|
logger.info(f"Starting {self.name}...")
|
|
56
96
|
|
|
57
97
|
def decorator(func):
|
|
@@ -66,4 +106,8 @@ class Task:
|
|
|
66
106
|
|
|
67
107
|
return wrapper
|
|
68
108
|
|
|
69
|
-
return decorator
|
|
109
|
+
return decorator
|
|
110
|
+
|
|
111
|
+
def shutdown(self, wait: bool = True) -> None:
|
|
112
|
+
"""Finaliza o executor manualmente quando necessário."""
|
|
113
|
+
self.process.shutdown(wait=wait)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyChannel
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.5
|
|
4
4
|
Summary: A Python concurrency library inspired by Go's goroutines and channels
|
|
5
5
|
Author: Brayan
|
|
6
6
|
Keywords: concurrency,channels,goroutines,parallelism,multiprocessing
|
|
@@ -11,8 +11,10 @@ Classifier: Programming Language :: Python :: 3
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
14
16
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
-
Requires-Python:
|
|
17
|
+
Requires-Python: >=3.10
|
|
16
18
|
Description-Content-Type: text/markdown
|
|
17
19
|
Requires-Dist: loky<4,>=3.5.6
|
|
18
20
|
Provides-Extra: dev
|
|
@@ -22,8 +24,8 @@ Requires-Dist: twine>=6.1; extra == "dev"
|
|
|
22
24
|
|
|
23
25
|
# PyChannel
|
|
24
26
|
|
|
25
|
-

|
|
28
|
+

|
|
27
29
|

|
|
28
30
|

|
|
29
31
|
|
|
@@ -108,6 +110,8 @@ resultado = channel.get() # 100
|
|
|
108
110
|
|
|
109
111
|
Se a função gerar uma exceção, ela permanece armazenada no `Future`. Quando existe um Channel, o objeto da exceção também é enviado para ele.
|
|
110
112
|
|
|
113
|
+
Os executores registrados pela `Task` são finalizados automaticamente quando o programa termina. Quando for necessário encerrar o pool antes do fim do programa, use `task.shutdown()`.
|
|
114
|
+
|
|
111
115
|
## `Channel`
|
|
112
116
|
|
|
113
117
|
O `Channel` transporta valores entre produtores e consumidores por meio de uma `multiprocessing.Queue`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# PyChannel
|
|
2
2
|
|
|
3
|
-

|
|
4
|
+

|
|
5
5
|

|
|
6
6
|

|
|
7
7
|
|
|
@@ -84,7 +84,9 @@ resultado = channel.get() # 100
|
|
|
84
84
|
| Com `Channel` e `Buffer` | O Channel recebe `False` durante o acúmulo e uma lista quando o lote fica pronto. |
|
|
85
85
|
| Com `Buffer`, sem `Channel` | O Buffer é atualizado e o resultado individual continua disponível no `Future`. |
|
|
86
86
|
|
|
87
|
-
Se a função gerar uma exceção, ela permanece armazenada no `Future`. Quando existe um Channel, o objeto da exceção também é enviado para ele.
|
|
87
|
+
Se a função gerar uma exceção, ela permanece armazenada no `Future`. Quando existe um Channel, o objeto da exceção também é enviado para ele.
|
|
88
|
+
|
|
89
|
+
Os executores registrados pela `Task` são finalizados automaticamente quando o programa termina. Quando for necessário encerrar o pool antes do fim do programa, use `task.shutdown()`.
|
|
88
90
|
|
|
89
91
|
## `Channel`
|
|
90
92
|
|
|
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "PyChannel"
|
|
7
|
-
version = "
|
|
7
|
+
version = "1.5"
|
|
8
8
|
description = "A Python concurrency library inspired by Go's goroutines and channels"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.10
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
11
|
authors = [
|
|
12
12
|
{ name = "Brayan" }
|
|
13
13
|
]
|
|
@@ -26,6 +26,8 @@ classifiers = [
|
|
|
26
26
|
"Programming Language :: Python :: 3.10",
|
|
27
27
|
"Programming Language :: Python :: 3.11",
|
|
28
28
|
"Programming Language :: Python :: 3.12",
|
|
29
|
+
"Programming Language :: Python :: 3.13",
|
|
30
|
+
"Programming Language :: Python :: 3.14",
|
|
29
31
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
30
32
|
]
|
|
31
33
|
dependencies = [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|