queuerPy 0.1.0__py3-none-any.whl
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.
- _version.py +7 -0
- queuer.py +580 -0
- queuerPy/__init__.py +77 -0
- queuerPy/_version.py +7 -0
- queuerPy/queuer.py +580 -0
- queuerPy/queuer_global.py +56 -0
- queuerPy/queuer_job.py +600 -0
- queuerPy/queuer_listener.py +73 -0
- queuerPy/queuer_next_interval.py +96 -0
- queuerPy/queuer_task.py +89 -0
- queuer_global.py +56 -0
- queuer_job.py +600 -0
- queuer_listener.py +73 -0
- queuer_next_interval.py +96 -0
- queuer_task.py +89 -0
- queuerpy-0.1.0.dist-info/METADATA +393 -0
- queuerpy-0.1.0.dist-info/RECORD +20 -0
- queuerpy-0.1.0.dist-info/WHEEL +5 -0
- queuerpy-0.1.0.dist-info/licenses/LICENSE +13 -0
- queuerpy-0.1.0.dist-info/top_level.txt +8 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Next interval function-related methods for the Python queuer implementation.
|
|
3
|
+
Mirrors Go's queuerNextInterval.go functionality.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
from typing import Any, Callable
|
|
8
|
+
|
|
9
|
+
from queuer_global import QueuerGlobalMixin
|
|
10
|
+
from model.worker import Worker
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class QueuerNextIntervalMixin(QueuerGlobalMixin):
|
|
16
|
+
"""
|
|
17
|
+
Mixin class containing next interval function-related methods for the Queuer.
|
|
18
|
+
Mirrors Go's queuerNextInterval.go functionality.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self):
|
|
22
|
+
super().__init__()
|
|
23
|
+
|
|
24
|
+
def add_next_interval_func(self, nif: Callable[..., Any]) -> Worker:
|
|
25
|
+
"""
|
|
26
|
+
Add a NextIntervalFunc to the worker's available next interval functions.
|
|
27
|
+
Takes a NextIntervalFunc and adds it to the worker's available_next_interval_funcs.
|
|
28
|
+
The function name is derived from the function using helper.get_task_name_from_interface.
|
|
29
|
+
|
|
30
|
+
:param nif: The next interval function to add
|
|
31
|
+
:return: The updated worker after adding the function
|
|
32
|
+
:raises ValueError: If function is None
|
|
33
|
+
:raises RuntimeError: If function already exists or database update fails
|
|
34
|
+
"""
|
|
35
|
+
from helper.task import get_task_name_from_interface
|
|
36
|
+
|
|
37
|
+
if nif is None:
|
|
38
|
+
raise ValueError("NextIntervalFunc cannot be None")
|
|
39
|
+
|
|
40
|
+
try:
|
|
41
|
+
nif_name = get_task_name_from_interface(nif)
|
|
42
|
+
except Exception as e:
|
|
43
|
+
raise RuntimeError(f"Error getting function name: {str(e)}")
|
|
44
|
+
|
|
45
|
+
if nif_name in self.worker.available_next_interval_funcs:
|
|
46
|
+
raise RuntimeError(f"NextIntervalFunc already exists: {nif_name}")
|
|
47
|
+
|
|
48
|
+
self.next_interval_funcs[nif_name] = nif
|
|
49
|
+
self.worker.available_next_interval_funcs.append(nif_name)
|
|
50
|
+
|
|
51
|
+
try:
|
|
52
|
+
worker = self.db_worker.update_worker(self.worker)
|
|
53
|
+
if not worker:
|
|
54
|
+
raise Exception("Worker could not be updated")
|
|
55
|
+
|
|
56
|
+
logger.info(f"NextInterval function added: {nif_name}")
|
|
57
|
+
return worker
|
|
58
|
+
except Exception as e:
|
|
59
|
+
raise RuntimeError(f"Error updating worker: {str(e)}")
|
|
60
|
+
|
|
61
|
+
def add_next_interval_func_with_name(
|
|
62
|
+
self, nif: Callable[..., Any], name: str
|
|
63
|
+
) -> Worker:
|
|
64
|
+
"""
|
|
65
|
+
Add a NextIntervalFunc to the worker's available next interval functions with a specific name.
|
|
66
|
+
Takes a NextIntervalFunc and a name, checks if the function is not None
|
|
67
|
+
and doesn't already exist in the worker's available next interval functions,
|
|
68
|
+
and adds it to the worker's available_next_interval_funcs.
|
|
69
|
+
|
|
70
|
+
This function is useful when you want to add a NextIntervalFunc
|
|
71
|
+
with a specific name that you control, rather than deriving it from the function itself.
|
|
72
|
+
|
|
73
|
+
:param nif: The next interval function to add
|
|
74
|
+
:param name: The specific name for the function
|
|
75
|
+
:return: The updated worker after adding the function with the specified name
|
|
76
|
+
:raises ValueError: If function is None
|
|
77
|
+
:raises RuntimeError: If function already exists or database update fails
|
|
78
|
+
"""
|
|
79
|
+
if nif is None:
|
|
80
|
+
raise ValueError("NextIntervalFunc cannot be None")
|
|
81
|
+
|
|
82
|
+
if name in self.worker.available_next_interval_funcs:
|
|
83
|
+
raise RuntimeError(f"NextIntervalFunc with name already exists: {name}")
|
|
84
|
+
|
|
85
|
+
self.next_interval_funcs[name] = nif
|
|
86
|
+
self.worker.available_next_interval_funcs.append(name)
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
worker = self.db_worker.update_worker(self.worker)
|
|
90
|
+
if not worker:
|
|
91
|
+
raise Exception("Worker could not be updated")
|
|
92
|
+
|
|
93
|
+
logger.info(f"NextInterval function added: {name}")
|
|
94
|
+
return worker
|
|
95
|
+
except Exception as e:
|
|
96
|
+
raise RuntimeError(f"Error updating worker: {str(e)}")
|
queuerPy/queuer_task.py
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Task-related methods for the Python queuer implementation.
|
|
3
|
+
Mirrors Go's queuerTask.go functionality.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
from typing import Any, Callable, Optional
|
|
8
|
+
|
|
9
|
+
from model.task import new_task, new_task_with_name
|
|
10
|
+
from model.task import Task
|
|
11
|
+
from queuer_global import QueuerGlobalMixin
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class QueuerTaskMixin(QueuerGlobalMixin):
|
|
17
|
+
"""
|
|
18
|
+
Mixin class containing task-related methods for the Queuer.
|
|
19
|
+
Mirrors Go's queuerTask.go functionality.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self):
|
|
23
|
+
super().__init__()
|
|
24
|
+
|
|
25
|
+
def add_task(self, task: Callable[..., Any]) -> Optional[Task]:
|
|
26
|
+
"""
|
|
27
|
+
Add a new task to the queuer.
|
|
28
|
+
Creates a new task with the provided task function, adds it to the worker's available tasks,
|
|
29
|
+
and updates the worker in the database.
|
|
30
|
+
The task name is automatically generated based on the task's function name.
|
|
31
|
+
|
|
32
|
+
:param task: The task function to add
|
|
33
|
+
:return: The newly created task
|
|
34
|
+
:raises RuntimeError: If task creation fails or task already exists
|
|
35
|
+
"""
|
|
36
|
+
task_name = task.__name__
|
|
37
|
+
if task_name in self.tasks:
|
|
38
|
+
raise RuntimeError(f"Task already exists: {task_name}")
|
|
39
|
+
|
|
40
|
+
try:
|
|
41
|
+
new_task_obj = new_task(task)
|
|
42
|
+
except Exception as e:
|
|
43
|
+
raise RuntimeError(f"Error creating new task: {str(e)}")
|
|
44
|
+
|
|
45
|
+
if new_task_obj.name in self.worker.available_tasks:
|
|
46
|
+
raise RuntimeError(f"Task already exists: {new_task_obj.name}")
|
|
47
|
+
|
|
48
|
+
self.tasks[new_task_obj.name] = new_task_obj
|
|
49
|
+
self.worker.available_tasks.append(new_task_obj.name)
|
|
50
|
+
|
|
51
|
+
# Update worker in DB
|
|
52
|
+
try:
|
|
53
|
+
self.db_worker.update_worker(self.worker)
|
|
54
|
+
except Exception as e:
|
|
55
|
+
raise RuntimeError(f"Error updating worker: {str(e)}")
|
|
56
|
+
|
|
57
|
+
logger.info(f"Task added: {new_task_obj.name}")
|
|
58
|
+
return new_task_obj
|
|
59
|
+
|
|
60
|
+
def add_task_with_name(self, task: Callable[..., Any], name: str) -> "Task":
|
|
61
|
+
"""
|
|
62
|
+
Add a new task with a specific name to the queuer.
|
|
63
|
+
Creates a new task with the provided task function and name, adds it to the worker's available tasks,
|
|
64
|
+
and updates the worker in the database.
|
|
65
|
+
|
|
66
|
+
:param task: The task function to add
|
|
67
|
+
:param name: The specific name for the task
|
|
68
|
+
:return: The newly created task
|
|
69
|
+
:raises RuntimeError: If task creation fails or task already exists
|
|
70
|
+
"""
|
|
71
|
+
try:
|
|
72
|
+
new_task_obj = new_task_with_name(task, name)
|
|
73
|
+
except Exception as e:
|
|
74
|
+
raise RuntimeError(f"Error creating new task: {str(e)}")
|
|
75
|
+
|
|
76
|
+
if name in self.worker.available_tasks:
|
|
77
|
+
raise RuntimeError(f"Task already exists: {name}")
|
|
78
|
+
|
|
79
|
+
self.tasks[new_task_obj.name] = new_task_obj
|
|
80
|
+
self.worker.available_tasks.append(new_task_obj.name)
|
|
81
|
+
|
|
82
|
+
# Update worker in DB
|
|
83
|
+
try:
|
|
84
|
+
self.db_worker.update_worker(self.worker)
|
|
85
|
+
except Exception as e:
|
|
86
|
+
raise RuntimeError(f"Error updating worker: {str(e)}")
|
|
87
|
+
|
|
88
|
+
logger.info(f"Task added: {new_task_obj.name}")
|
|
89
|
+
return new_task_obj
|
queuer_global.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from typing import Any, Callable, Dict, Optional
|
|
2
|
+
from core.broadcaster import new_broadcaster
|
|
3
|
+
from core.listener import Listener
|
|
4
|
+
from database.db_job import JobDBHandler
|
|
5
|
+
from database.db_worker import WorkerDBHandler
|
|
6
|
+
from helper.database import Database, DatabaseConfiguration, new_database
|
|
7
|
+
from helper.logging import get_logger
|
|
8
|
+
from model.job import Job
|
|
9
|
+
from model.task import Task
|
|
10
|
+
from model.worker import Worker
|
|
11
|
+
|
|
12
|
+
logger = get_logger()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class QueuerGlobalMixin:
|
|
16
|
+
def __init__(self):
|
|
17
|
+
self.running: bool = False
|
|
18
|
+
|
|
19
|
+
# DB
|
|
20
|
+
self.db_job: JobDBHandler
|
|
21
|
+
self.db_worker: WorkerDBHandler
|
|
22
|
+
|
|
23
|
+
# Broadcaster
|
|
24
|
+
self.job_insert_broadcaster = new_broadcaster("job.INSERT")
|
|
25
|
+
self.job_update_broadcaster = new_broadcaster("job.UPDATE")
|
|
26
|
+
self.job_delete_broadcaster = new_broadcaster("job.DELETE")
|
|
27
|
+
|
|
28
|
+
# Listener
|
|
29
|
+
self.job_insert_listener = Listener[Job](self.job_insert_broadcaster)
|
|
30
|
+
self.job_update_listener = Listener[Job](self.job_update_broadcaster)
|
|
31
|
+
self.job_delete_listener = Listener[Job](self.job_delete_broadcaster)
|
|
32
|
+
|
|
33
|
+
# Ticker
|
|
34
|
+
self.heartbeat_ticker: Optional[Any] = None
|
|
35
|
+
self.poll_job_ticker: Optional[Any] = None
|
|
36
|
+
|
|
37
|
+
self.worker: Worker
|
|
38
|
+
self.tasks: Dict[str, Task] = {}
|
|
39
|
+
self.next_interval_funcs: Dict[str, Callable[..., Any]] = {}
|
|
40
|
+
|
|
41
|
+
def initialise(
|
|
42
|
+
self,
|
|
43
|
+
db_config: DatabaseConfiguration,
|
|
44
|
+
encryption_key: str = "",
|
|
45
|
+
):
|
|
46
|
+
# Database connection
|
|
47
|
+
self.database: Database = new_database("queuer", db_config, logger)
|
|
48
|
+
self.DB = self.database.instance
|
|
49
|
+
|
|
50
|
+
# Database handlers
|
|
51
|
+
self.db_job: JobDBHandler = JobDBHandler(
|
|
52
|
+
self.database, db_config.with_table_drop, encryption_key
|
|
53
|
+
)
|
|
54
|
+
self.db_worker: WorkerDBHandler = WorkerDBHandler(
|
|
55
|
+
self.database, db_config.with_table_drop
|
|
56
|
+
)
|