Skip to content

Commit 15ed128

Browse files
committed
🎉 initial commit
1 parent 74bd510 commit 15ed128

4 files changed

Lines changed: 169 additions & 0 deletions

File tree

processpy/PManager.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import multiprocessing
2+
from typing import Any, Callable, Dict
3+
4+
class ProcessManager(object):
5+
def __init__(self, func: Callable, kill_previous: Any = False, concurrent_running: Any = False) -> None:
6+
"""ProcessManager initializer
7+
8+
Args:
9+
func (Callable): function to be executed
10+
kill_previous (Any, optional): Do you want to kill previous process? if not, new process won't be executed if concurrent is set to False.
11+
If True, it will kill the unfinished previous process and start the new one.
12+
Defaults to False.
13+
concurrent_running (Any, optional): If True, all the process of the function will run concurrently. Defaults to False.
14+
15+
Raises:
16+
ValueError: kill_previous and concurrent_running can't be used together. If you kill previous, what do you wanna run concurrently?
17+
"""
18+
if concurrent_running and kill_previous:
19+
raise ValueError("Using kill_previous is not allowed while using concurrent_running.")
20+
self.func = func
21+
self.kill_previous = kill_previous
22+
self.concurrent_running = concurrent_running
23+
24+
"""
25+
We really don't need to keep track of multiple process. We will need that only when concurrent_running is true
26+
and we don't need to terminate any process. So, no use of the process ids.
27+
In the future, all the process management will be added if needed.
28+
"""
29+
self.process = None
30+
31+
def run(self, kwargs: Dict = None) -> None:
32+
""" create a new process of the function
33+
34+
Args:
35+
kwargs (Dict, optional): arguments to be passed to your function. Defaults to None.
36+
"""
37+
if self.concurrent_running == False and self.process is not None and self.process.is_alive():
38+
if self.kill_previous:
39+
self.kill()
40+
else:
41+
return
42+
43+
if kwargs == None:
44+
self.process = multiprocessing.Process(target=self.func)
45+
else:
46+
self.process = multiprocessing.Process(target=self.func, kwargs=kwargs)
47+
self.process.daemon = True
48+
self.process.start()
49+
50+
def kill(self) -> None:
51+
"""terminate the currently running process
52+
"""
53+
if self.process is not None and self.process.is_alive:
54+
self.process.terminate()

processpy/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .PManager import ProcessManager
2+
3+
__all__ = ["ProcessManager"]

pyproject.toml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
[tool.poetry]
2+
name = "processpy"
3+
version = "0.1.0"
4+
description = "Python Process Manager"
5+
authors = [
6+
"Nazmul Hasan <edufornazmul@gmail.com>"
7+
]
8+
9+
license = "MIT"
10+
readme = "README.md"
11+
repository = "https://github.com/nazmulnnb/processpy"
12+
13+
classifiers = [
14+
'Operating System :: OS Independent',
15+
'Programming Language :: Python',
16+
'Programming Language :: Python :: 3',
17+
'Programming Language :: Python :: 3.6',
18+
'Programming Language :: Python :: 3.7',
19+
'Programming Language :: Python :: 3.8',
20+
'Programming Language :: Python :: 3.9',
21+
'Programming Language :: Python :: 3 :: Only',
22+
]
23+
24+
[tool.poetry.dependencies]
25+
python = "^3.6"
26+
27+
[tool.poetry.dev-dependencies]
28+
pytest = "^7.1"
29+
30+
[build-system]
31+
requires = ["poetry-core>=1.0.0"]
32+
build-backend = "poetry.core.masonry.api"

readme.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Python Process Manager (processpy)
2+
3+
4+
processpy is simple process manager for python.
5+
If you want to run multiple process for the same function, this tool is for you.
6+
7+
* You can run multiple process of the same function concurrently.
8+
* You can choose to kill previous running process before running a new process of the same function.
9+
* You can choose to ignore new process of the same function if it's already running.
10+
11+
12+
## Installation
13+
14+
```bash
15+
pip install processpy
16+
```
17+
18+
## Example (No concurrency and no previous kill)
19+
20+
```python
21+
from processpy import ProcessManager
22+
import time
23+
24+
def sum(a, b):
25+
time.sleep(30)
26+
print(a+b)
27+
28+
sum_process = ProcessManager(sum, kill_previous=False, concurrent_running=False)
29+
sum_process.run({'a': 10, 'b': 20})
30+
time.sleep(5)
31+
32+
"""
33+
The following will not run. Because concurrent run is false and kill previous is also false. So, it will simply return with doing nothing and let the previous run.
34+
"""
35+
sum_process.run({'a': 10, 'b': 20})
36+
37+
```
38+
39+
## Example (No concurrency but with previous kill)
40+
```python
41+
from processpy import ProcessManager
42+
import time
43+
44+
def sum(a, b):
45+
time.sleep(30)
46+
print(a+b)
47+
48+
sum_process = ProcessManager(sum, kill_previous=True, concurrent_running=False)
49+
sum_process.run({'a': 10, 'b': 20})
50+
time.sleep(5)
51+
52+
"""
53+
The following will kill the previous unfinished process and run. Because concurrent run is false and kill previous is True. So, it will simply kill the previous unfinished process. If previous one is already finished, nothing to kill.
54+
"""
55+
sum_process.run({'a': 10, 'b': 20})
56+
```
57+
58+
## Example (with concurrency)
59+
```python
60+
from processpy import ProcessManager
61+
import time
62+
63+
def sum(a, b):
64+
time.sleep(30)
65+
print(a+b)
66+
67+
sum_process = ProcessManager(sum, concurrent_running=True)
68+
sum_process.run({'a': 10, 'b': 20})
69+
time.sleep(5)
70+
71+
"""
72+
The following will run alongside of the previous process.
73+
"""
74+
sum_process.run({'a': 10, 'b': 20})
75+
```
76+
77+
## You can also kill the running process (if concurrent_running=False )
78+
```python
79+
sub_process.kill()
80+
```

0 commit comments

Comments
 (0)