Compare commits

...

8 Commits
v1.0.1 ... main

Author SHA1 Message Date
f5e32e4824 🐛 add py.typed 2024-10-23 00:26:55 +08:00
00d20658ee 更新上游依赖版本,性能提升225倍 2024-10-20 22:09:45 +08:00
d5dd67b31d 🐛 fix from mypy import 2024-10-19 21:07:50 +08:00
1bf1380b63 🐛 fix uninit ctx 2024-10-14 23:27:06 +08:00
5d505d1c89 🐛 fix uninit ctx 2024-10-14 23:26:48 +08:00
9c50844195 🐛 remove debug output 2024-10-13 23:56:00 +08:00
e151a7af0c first commit 2024-10-13 17:28:37 +08:00
5cb3424ad0 first commit 2024-10-13 00:12:24 +08:00
6 changed files with 76 additions and 49 deletions

View File

@ -5,6 +5,11 @@ from magicoca.chan import Chan
class Context: class Context:
def __init__(self): def __init__(self):
"""
main_chan: Chan[Any] = main to sub
sub_chan: Chan[Any] = sub to main
哪个进程发送用哪个
"""
self.main_chan: Chan[Any] = Chan[Any]() # main to sub self.main_chan: Chan[Any] = Chan[Any]() # main to sub
self.sub_chan: Chan[Any] = Chan[Any]() # sub to main self.sub_chan: Chan[Any] = Chan[Any]() # sub to main

View File

@ -1,26 +1,30 @@
from multiprocessing import Process as _Process from multiprocessing import Process as _Process
from typing import Callable, Any from typing import Callable, Any
from typing import TypeAlias
from croterline.context import Context from croterline.context import Context
from croterline.utils import IsMainProcess from croterline.utils import IsMainProcess
type ProcessFuncType = Callable[[tuple[Any, ...], dict[str, Any]], None] ProcessFuncType: TypeAlias = Callable[[tuple[Any, ...], dict[str, Any]], None]
_processes: dict[str, "SubProcess"] = {}
_current_ctx: "Context | None" = None # 注入当前进程上下文 _current_ctx: "Context | None" = None # 注入当前进程上下文
class SubProcess: class SubProcess:
def __init__( def __init__(
self, name: str, func: ProcessFuncType, ctx: Context = Context, *args, **kwargs self,
name: str,
func: ProcessFuncType,
ctx: Context = Context(),
*args,
**kwargs,
): ):
self.name = name self.name = name
self.func = func self.func = func
self.ctx = ctx self.ctx = ctx
self.args = args self.args = args
self.kwargs = kwargs self.kwargs = kwargs
self.process: _Process | None = None self.process: _Process | None = None
def start(self): def start(self):
@ -30,54 +34,25 @@ class SubProcess:
kwargs=self.kwargs, kwargs=self.kwargs,
) )
self.process.start() self.process.start()
set_process(self.name, self)
def terminate(self): def terminate(self):
self.process.terminate() self.process.terminate()
set_process(self.name, None)
def join(self, timeout: float = 0): def join(self, timeout: float = 0):
self.process.join(timeout=timeout) self.process.join(timeout=timeout)
set_process(self.name, None)
def set_process(name: str, process: SubProcess | None): def get_ctx() -> Context | None:
_processes[name] = process
def get_process(name: str) -> SubProcess | None:
"""
获取进程对象在主进程中调用只可在主进程调用
Args:
name: 进程名称
Returns:
进程对象
"""
if not IsMainProcess:
raise RuntimeError(
"get_process with specific name can only be called in the main process."
)
return _processes.get(name, None)
def get_ctx(name: str | None = None) -> Context | None:
""" """
获取进程上下文在主进程中调用需指定进程名称若在子进程中调用则无需指定进程名称 获取进程上下文在主进程中调用需指定进程名称若在子进程中调用则无需指定进程名称
Returns: Returns:
进程上下文 进程上下文
""" """
if name is not None: if IsMainProcess:
if not IsMainProcess: raise RuntimeError(
raise RuntimeError( "get_ctx without name can only be called in the sub process."
"get_ctx with specific name can only be called in the main process." )
) return _current_ctx
return _processes.get(name, None).ctx
else:
if IsMainProcess:
raise RuntimeError(
"get_ctx without name can only be called in the sub process."
)
return _current_ctx
def _wrapper(func: ProcessFuncType, ctx: Context, *args, **kwargs): def _wrapper(func: ProcessFuncType, ctx: Context, *args, **kwargs):

1
croterline/py.typed Normal file
View File

@ -0,0 +1 @@
a

45
pdm.lock generated
View File

@ -5,7 +5,7 @@
groups = ["default", "dev"] groups = ["default", "dev"]
strategy = ["inherit_metadata"] strategy = ["inherit_metadata"]
lock_version = "4.5.0" lock_version = "4.5.0"
content_hash = "sha256:4affe52c3e672fd14a8c7a461b5a250cda491156c7673dd316492dc40f5e2512" content_hash = "sha256:52094c6a65de05f06dafee55f769b4938366fa046b8dceab6c97207153b5920d"
[[metadata.targets]] [[metadata.targets]]
requires_python = ">=3.10" requires_python = ">=3.10"
@ -98,13 +98,49 @@ files = [
[[package]] [[package]]
name = "magicoca" name = "magicoca"
version = "1.0.1" version = "1.0.6"
requires_python = ">=3.10" requires_python = ">=3.10"
summary = "A communication library for Python" summary = "A communication library for Python"
groups = ["default"] groups = ["default"]
files = [ files = [
{file = "magicoca-1.0.1-py3-none-any.whl", hash = "sha256:69e04be77f9c02d3d0730dc4e739246f4bdefee8b78631040b464cd98cdde51c"}, {file = "magicoca-1.0.6-py3-none-any.whl", hash = "sha256:3c62d6c3e87b3b5a13e0fd5b5fb674374355326684ab4421f2ac8a4c5127455e"},
{file = "magicoca-1.0.1.tar.gz", hash = "sha256:0dbc9a35609db92ec79076f7126566c1e71bd4b853909ecbad9221dcc7fd6f31"}, {file = "magicoca-1.0.6.tar.gz", hash = "sha256:e32ec57d67e64232dc7681c5095166e6a0ee3d27048d7115aa2b09ce4e7d9ff6"},
]
[[package]]
name = "mypy"
version = "1.12.1"
requires_python = ">=3.8"
summary = "Optional static typing for Python"
groups = ["dev"]
dependencies = [
"mypy-extensions>=1.0.0",
"tomli>=1.1.0; python_version < \"3.11\"",
"typing-extensions>=4.6.0",
]
files = [
{file = "mypy-1.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3d7d4371829184e22fda4015278fbfdef0327a4b955a483012bd2d423a788801"},
{file = "mypy-1.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f59f1dfbf497d473201356966e353ef09d4daec48caeacc0254db8ef633a28a5"},
{file = "mypy-1.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b947097fae68004b8328c55161ac9db7d3566abfef72d9d41b47a021c2fba6b1"},
{file = "mypy-1.12.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:96af62050971c5241afb4701c15189ea9507db89ad07794a4ee7b4e092dc0627"},
{file = "mypy-1.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:d90da248f4c2dba6c44ddcfea94bb361e491962f05f41990ff24dbd09969ce20"},
{file = "mypy-1.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1230048fec1380faf240be6385e709c8570604d2d27ec6ca7e573e3bc09c3735"},
{file = "mypy-1.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:02dcfe270c6ea13338210908f8cadc8d31af0f04cee8ca996438fe6a97b4ec66"},
{file = "mypy-1.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5a437c9102a6a252d9e3a63edc191a3aed5f2fcb786d614722ee3f4472e33f6"},
{file = "mypy-1.12.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:186e0c8346efc027ee1f9acf5ca734425fc4f7dc2b60144f0fbe27cc19dc7931"},
{file = "mypy-1.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:673ba1140a478b50e6d265c03391702fa11a5c5aff3f54d69a62a48da32cb811"},
{file = "mypy-1.12.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9fb83a7be97c498176fb7486cafbb81decccaef1ac339d837c377b0ce3743a7f"},
{file = "mypy-1.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:389e307e333879c571029d5b93932cf838b811d3f5395ed1ad05086b52148fb0"},
{file = "mypy-1.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:94b2048a95a21f7a9ebc9fbd075a4fcd310410d078aa0228dbbad7f71335e042"},
{file = "mypy-1.12.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ee5932370ccf7ebf83f79d1c157a5929d7ea36313027b0d70a488493dc1b179"},
{file = "mypy-1.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:19bf51f87a295e7ab2894f1d8167622b063492d754e69c3c2fed6563268cb42a"},
{file = "mypy-1.12.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d34167d43613ffb1d6c6cdc0cc043bb106cac0aa5d6a4171f77ab92a3c758bcc"},
{file = "mypy-1.12.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:427878aa54f2e2c5d8db31fa9010c599ed9f994b3b49e64ae9cd9990c40bd635"},
{file = "mypy-1.12.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5fcde63ea2c9f69d6be859a1e6dd35955e87fa81de95bc240143cf00de1f7f81"},
{file = "mypy-1.12.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:d54d840f6c052929f4a3d2aab2066af0f45a020b085fe0e40d4583db52aab4e4"},
{file = "mypy-1.12.1-cp313-cp313-win_amd64.whl", hash = "sha256:20db6eb1ca3d1de8ece00033b12f793f1ea9da767334b7e8c626a4872090cf02"},
{file = "mypy-1.12.1-py3-none-any.whl", hash = "sha256:ce561a09e3bb9863ab77edf29ae3a50e65685ad74bba1431278185b7e5d5486e"},
{file = "mypy-1.12.1.tar.gz", hash = "sha256:f5b3936f7a6d0e8280c9bdef94c7ce4847f5cdfc258fbb2c29a8c1711e8bb96d"},
] ]
[[package]] [[package]]
@ -199,7 +235,6 @@ version = "4.12.2"
requires_python = ">=3.8" requires_python = ">=3.8"
summary = "Backported and Experimental Type Hints for Python 3.8+" summary = "Backported and Experimental Type Hints for Python 3.8+"
groups = ["dev"] groups = ["dev"]
marker = "python_version < \"3.11\""
files = [ files = [
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},

View File

@ -6,7 +6,7 @@ authors = [
{name = "snowykami", email = "snowykami@outlook.com"}, {name = "snowykami", email = "snowykami@outlook.com"},
] ]
dependencies = [ dependencies = [
"magicoca>=1.0.1", "magicoca>=1.0.6",
] ]
requires-python = ">=3.10" requires-python = ">=3.10"
readme = "README.md" readme = "README.md"
@ -25,6 +25,7 @@ tag_regex = '^v(?:\D*)?(?P<version>([1-9][0-9]*!)?(0|[1-9][0-9]*)(\.(0|[1-9][0-9
dev = [ dev = [
"pytest>=8.3.3", "pytest>=8.3.3",
"black>=24.10.0", "black>=24.10.0",
"mypy>=1.11.2",
] ]
[tool.pdm] [tool.pdm]
distribution = true distribution = true

View File

@ -5,6 +5,8 @@ from croterline.process import SubProcess, get_ctx
def p_func(*args, **kwargs): def p_func(*args, **kwargs):
print("Args", args)
print("Kwargs", kwargs)
i = 0 i = 0
ctx = get_ctx() ctx = get_ctx()
while True: while True:
@ -15,10 +17,16 @@ def p_func(*args, **kwargs):
ctx.sub_chan << "end" ctx.sub_chan << "end"
def p_func2(*args, **kwargs):
print("args: ", args)
print("kwargs: ", kwargs)
raise Exception("Test")
class TestSubProcess: class TestSubProcess:
def test_run(self): def test_run(self):
print("start") print("start")
sp = SubProcess("test", p_func, Context()) sp = SubProcess("test", p_func, Context(), 1, 2, 3, k1=1, k2=2)
sp.start() sp.start()
while True: while True:
@ -30,5 +38,7 @@ class TestSubProcess:
print("finished") print("finished")
sp.terminate() sp.terminate()
def test_decorator(self): def test_input(self):
pass print("test_input")
sp = SubProcess("test2", p_func2, Context(), 1, 2, 3, host=1, port=2)
sp.start()